//Filename    : PIMNavigator.cs
//Part of     : PCSAPI C# examples
//Description : Implementation of PIM Navigator main dialog
//Version     : 3.2
//
//This example is only to be used with PC Connectivity API version 2.2.
//Compability ("as is") with future versions is not quaranteed.
//
//Copyright (c) 2007 Nokia Corporation.
//
//This material, including but not limited to documentation and any related
//computer programs, is protected by intellectual property rights of Nokia
//Corporation and/or its licensors.
//All rights are reserved. Reproducing, modifying, translating, or
//distributing any or all of this material requires the prior written consent
//of Nokia Corporation. Nokia Corporation retains the right to make changes
//to this material at any time without notice. A copyright license is hereby
//granted to download and print a copy of this material for personal use only.
//No other license to any other intellectual property rights is granted. The
//material is provided "as is" without warranty of any kind, either express or
//implied, including without limitation, any warranty of non-infringement,
//merchantability and fitness for a particular purpose. In no event shall
//Nokia Corporation be liable for any direct, indirect, special, incidental,
//or consequential loss or damages, including but not limited to, lost profits
//or revenue,loss of use, cost of substitute program, or loss of data or
//equipment arising out of the use or inability to use the material, even if
//Nokia Corporation has been advised of the likelihood of such damages occurring.
using System.Runtime.InteropServices;
using System.Linq;
namespace CSPimNavigator.NET
{
    using PCCSErrors;
    using PCCAPIUtils;
    using CONADefinitions;
    using System;
    using CONADeviceManagement;
    using CAContentAccess;
    using PCCSTypeDefinitions;
    using System.Windows.Forms;

    public class PIMNavigator : System.Windows.Forms.Form
    {
        public delegate void InsertNotificationDelegate(string strNotification);

        private const int m_iIconPhoneIndex = 0;
        private const int m_iIconNoPhoneIndex = 1;
        private const int m_iIconContactsIndex = 2;
        private const int m_iIconContactIndex = 3;
        private const int m_iIconSMSMessagesIndex = 4;
        private const int m_iIconSMSIndex = 5;
        private const int m_iIconMMSMessagesIndex = 6;
        private const int m_iIconMMSIndex = 7;
        private const int m_iIconCalendarIndex = 8;
        private const int m_iIconCalendarItemIndex = 9;
        private const int m_iIconBookmarkIndex = 10;
        private const int m_iIconBookmarkItemIndex = 11;

        // Device manager handle
        private int m_hDMHandle = 0;
        private CONADefinitions.DeviceNotifyCallbackDelegate pDeviceCallBack;
        private CAContentAccess.DAContentAccessDefinitions.CANotifyCallbackDelegate pCANotifyCallBack;
        private CAContentAccess.DAContentAccessDefinitions.CAOperationCallbackDelegate pCAOperationCallback;
        private int m_hContacts = 0;
        private int m_hSMS = 0;
        private int m_hMMS = 0;
        private int m_hCalendar = 0;
        private int m_hBookmark = 0;
        private int m_hCurrentConnection = 0;
        private string m_strCurrentContactsSerialNumber = "";
        private string m_strCurrentSMSSerialNumber = "";
        private string m_strCurrentMMSSerialNumber = "";
        private string m_strCurrentCalendarSerialNumber = "";
        private string m_strCurrentBookmarkSerialNumber = "";
        private string m_strFile;
        private IntPtr m_pContactBuffer = IntPtr.Zero;
        private IntPtr m_pCalendarBuffer = IntPtr.Zero;
        private IntPtr m_pSMSBuffer = IntPtr.Zero;
        private IntPtr m_pMMSBuffer = IntPtr.Zero;
        private IntPtr m_pBookmarkBuffer = IntPtr.Zero;
        internal System.Windows.Forms.Button BTN_NewFolder;
        private bool bRefresh = false;
        private NotificationsDlg NotificationsDialog;
        internal Button buttonNotifications;
        private PictureBox pictureBox1;

        private static bool fTerminateCalled;

        //==================================================================
        //
        // Program start point
        //
        //==================================================================
        [System.STAThread()]
        public static void Main()
        {
            // Starts the application.
            //Application.Run(new PIMNavigator());
        }

        //===================================================================
        //
        // Structure to map CA_FOLDER_INFO "permanently" into managed memory 
        // 
        //===================================================================
        private struct CAFolderInfo
        {
            public int iFolderId;
            public int iOptions;
            public string strName;
            public string strPath;
            public bool iSubfolderCount;
            public bool bIsChild;
        }

        //===================================================================
        // MapCFIToCAFolderInfo
        // 
        // Maps CA_FOLDER_INFO structure to CaFolderInfo structure
        //   NOTE: Mapping is simple, parent and child folder info is lost
        // 
        //===================================================================
        private CAFolderInfo MapCFIToCAFolderInfo(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO CFI)
        {
            CAFolderInfo functionReturnValue = new CAFolderInfo();
            functionReturnValue.iFolderId = CFI.iFolderId;
            functionReturnValue.iOptions = CFI.iOptions;
            functionReturnValue.strName = CFI.pstrName;
            functionReturnValue.strPath = CFI.pstrPath;
            functionReturnValue.iSubfolderCount = CFI.iSubFolderCount != 0;
            functionReturnValue.bIsChild = (CFI.pParent != IntPtr.Zero);
            return functionReturnValue;
            return functionReturnValue;
        }

        //===================================================================
        // MapCAFolderInfoToCFI
        // 
        // Maps CaFolderInfo structure to CA_FOLDER_INFO structure
        //   NOTE: Mapping is simple, parent and child folder info is missing
        // 
        //===================================================================
        private CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO MapCAFolderInfoToCFI(CAFolderInfo caFolder)
        {
            CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO functionReturnValue = new CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO();
            functionReturnValue.iSize = Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO));
            functionReturnValue.iFolderId = caFolder.iFolderId;
            functionReturnValue.iOptions = caFolder.iOptions;
            functionReturnValue.pstrName = caFolder.strName;
            functionReturnValue.pstrPath = caFolder.strPath;
            functionReturnValue.iSubFolderCount = 0;
            functionReturnValue.pSubFolders = IntPtr.Zero;
            functionReturnValue.pParent = IntPtr.Zero;
            return functionReturnValue;
        }

        //===================================================================
        //
        // Structure to map CA_ITEM_ID "permanently" into managed memory 
        // 
        //===================================================================
        private struct CAItemID
        {
            public int iFolderId;
            public int iTemporaryID;
            public byte[] abUID;
            public int iStatus;
        }

        //===================================================================
        // MapUIDToCAItemID
        // 
        // Maps CA_ITEM_ID structure to CaItemID structure
        // 
        //===================================================================
        private CAItemID MapUIDToCAItemID(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID)
        {
            CAItemID functionReturnValue = new CAItemID();
            functionReturnValue.iFolderId = UID.iFolderId;
            functionReturnValue.iTemporaryID = UID.iTemporaryID;
            functionReturnValue.iStatus = UID.iStatus;
            if (UID.iUidLen > 0)
            {
                functionReturnValue.abUID = new byte[UID.iUidLen];
                Marshal.Copy(UID.pbUid, functionReturnValue.abUID, 0, UID.iUidLen);
            }
            else
            {
                functionReturnValue.abUID = null;
            }
            return functionReturnValue;
        }

        //===================================================================
        // MapCAItemIDToUID
        // 
        // Maps CaItemID structure to CA_ITEM_ID structure
        // Remember to free allocated memory after use (FreeUIDMappingMemory).
        // 
        //===================================================================
        private CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID MapCAItemIDToUID(CAItemID caID)
        {
            CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID functionReturnValue = new CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID();
            functionReturnValue.iSize = Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID));
            functionReturnValue.iFolderId = caID.iFolderId;
            functionReturnValue.iTemporaryID = caID.iTemporaryID;
            functionReturnValue.iStatus = caID.iStatus;
            if (caID.abUID == null)
            {
                functionReturnValue.iUidLen = 0;
                functionReturnValue.pbUid = IntPtr.Zero;
            }
            else
            {
                int iSize = caID.abUID.GetUpperBound(0) - caID.abUID.GetLowerBound(0)+1;
                functionReturnValue.iUidLen = iSize;
                functionReturnValue.pbUid = Marshal.AllocHGlobal(iSize);
                Marshal.Copy(caID.abUID, 0, functionReturnValue.pbUid, iSize);
            }
            return functionReturnValue;
        }

        //===================================================================
        // FreeUIDMappingMemory
        //
        //   Free's memory allocated by MapCAItemIDToUID call.
        //
        //===================================================================
        private void FreeUIDMappingMemory(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID)
        {
            Marshal.FreeHGlobal(UID.pbUid);
            UID.pbUid = IntPtr.Zero;
        }

#region " Windows Form Designer generated code "

        public PIMNavigator()
            : base()
        {

            //This call is required by the Windows Form Designer.
            InitializeComponent();

            //Add any initialization after the InitializeComponent() call

        }

        //Form overrides dispose to clean up the component list.
        protected override void Dispose(bool disposing)
	{
		if (disposing)
		{
			if (!fTerminateCalled)
			{
                CloseContactsConnection();
                CloseCalendarConnection();
                CloseSMSConnection();
                CloseMMSConnection();
                CloseBookmarkConnection();
                UninitializePCSAPI();
				fTerminateCalled = true;
			}
			if ((components != null))
			{
				components.Dispose();
			}
		}
		base.Dispose(disposing);
	}

        //Required by the Windows Form Designer
        private System.ComponentModel.IContainer components;

        //NOTE: The following procedure is required by the Windows Form Designer
        //It can be modified using the Windows Form Designer.  
        //Do not modify it using the code editor.
        internal System.Windows.Forms.TreeView TVW_Navigator;
        internal System.Windows.Forms.ListView LVW_ItemList;
        internal System.Windows.Forms.ColumnHeader ColumnHeader1;
        internal System.Windows.Forms.ColumnHeader ColumnHeader2;
        internal System.Windows.Forms.Button BTN_Close;
        internal System.Windows.Forms.Button BTN_New;
        internal System.Windows.Forms.Button BTN_Delete;
        internal System.Windows.Forms.Button BTN_Refresh;
        internal System.Windows.Forms.ImageList ImageList1;
        internal System.Windows.Forms.Timer Timer1;
        internal System.Windows.Forms.Button BTN_Save;
        private TreeNode _smsNode;

        [System.Diagnostics.DebuggerStepThrough()]
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PIMNavigator));
            this.TVW_Navigator = new System.Windows.Forms.TreeView();
            this.ImageList1 = new System.Windows.Forms.ImageList(this.components);
            this.LVW_ItemList = new System.Windows.Forms.ListView();
            this.ColumnHeader1 = new System.Windows.Forms.ColumnHeader();
            this.ColumnHeader2 = new System.Windows.Forms.ColumnHeader();
            this.BTN_Close = new System.Windows.Forms.Button();
            this.BTN_New = new System.Windows.Forms.Button();
            this.BTN_Delete = new System.Windows.Forms.Button();
            this.BTN_Refresh = new System.Windows.Forms.Button();
            this.Timer1 = new System.Windows.Forms.Timer(this.components);
            this.BTN_Save = new System.Windows.Forms.Button();
            this.BTN_NewFolder = new System.Windows.Forms.Button();
            this.buttonNotifications = new System.Windows.Forms.Button();
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            this.SuspendLayout();
            // 
            // TVW_Navigator
            // 
            this.TVW_Navigator.ImageIndex = 0;
            this.TVW_Navigator.ImageList = this.ImageList1;
            this.TVW_Navigator.Location = new System.Drawing.Point(8, 8);
            this.TVW_Navigator.Name = "TVW_Navigator";
            this.TVW_Navigator.SelectedImageIndex = 0;
            this.TVW_Navigator.Size = new System.Drawing.Size(264, 376);
            this.TVW_Navigator.TabIndex = 0;
            this.TVW_Navigator.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.TVW_Navigator_BeforeExpand);
            this.TVW_Navigator.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.TVW_Navigator_AfterSelect);
            // 
            // ImageList1
            // 
            this.ImageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("ImageList1.ImageStream")));
            this.ImageList1.TransparentColor = System.Drawing.Color.Transparent;
            this.ImageList1.Images.SetKeyName(0, "");
            this.ImageList1.Images.SetKeyName(1, "");
            this.ImageList1.Images.SetKeyName(2, "");
            this.ImageList1.Images.SetKeyName(3, "");
            this.ImageList1.Images.SetKeyName(4, "");
            this.ImageList1.Images.SetKeyName(5, "");
            this.ImageList1.Images.SetKeyName(6, "");
            this.ImageList1.Images.SetKeyName(7, "");
            this.ImageList1.Images.SetKeyName(8, "");
            this.ImageList1.Images.SetKeyName(9, "");
            this.ImageList1.Images.SetKeyName(10, "BookmarkFolder.ico");
            this.ImageList1.Images.SetKeyName(11, "BookMark.ico");
            // 
            // LVW_ItemList
            // 
            this.LVW_ItemList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.ColumnHeader1,
            this.ColumnHeader2});
            this.LVW_ItemList.Location = new System.Drawing.Point(280, 8);
            this.LVW_ItemList.Name = "LVW_ItemList";
            this.LVW_ItemList.Size = new System.Drawing.Size(264, 376);
            this.LVW_ItemList.TabIndex = 1;
            this.LVW_ItemList.UseCompatibleStateImageBehavior = false;
            this.LVW_ItemList.View = System.Windows.Forms.View.Details;
            // 
            // ColumnHeader1
            // 
            this.ColumnHeader1.Text = "Field";
            this.ColumnHeader1.Width = 120;
            // 
            // ColumnHeader2
            // 
            this.ColumnHeader2.Text = "Data";
            this.ColumnHeader2.Width = 140;
            // 
            // BTN_Close
            // 
            this.BTN_Close.Location = new System.Drawing.Point(470, 392);
            this.BTN_Close.Name = "BTN_Close";
            this.BTN_Close.Size = new System.Drawing.Size(74, 24);
            this.BTN_Close.TabIndex = 2;
            this.BTN_Close.Text = "Close";
            this.BTN_Close.Click += new System.EventHandler(this.BTN_Close_Click);
            // 
            // BTN_New
            // 
            this.BTN_New.Enabled = false;
            this.BTN_New.Location = new System.Drawing.Point(8, 392);
            this.BTN_New.Name = "BTN_New";
            this.BTN_New.Size = new System.Drawing.Size(74, 24);
            this.BTN_New.TabIndex = 3;
            this.BTN_New.Text = "New";
            this.BTN_New.Click += new System.EventHandler(this.BTN_New_Click);
            // 
            // BTN_Delete
            // 
            this.BTN_Delete.Enabled = false;
            this.BTN_Delete.Location = new System.Drawing.Point(162, 392);
            this.BTN_Delete.Name = "BTN_Delete";
            this.BTN_Delete.Size = new System.Drawing.Size(74, 24);
            this.BTN_Delete.TabIndex = 4;
            this.BTN_Delete.Text = "Delete";
            this.BTN_Delete.Click += new System.EventHandler(this.BTN_Delete_Click);
            // 
            // BTN_Refresh
            // 
            this.BTN_Refresh.Location = new System.Drawing.Point(393, 392);
            this.BTN_Refresh.Name = "BTN_Refresh";
            this.BTN_Refresh.Size = new System.Drawing.Size(74, 24);
            this.BTN_Refresh.TabIndex = 5;
            this.BTN_Refresh.Text = "Refresh";
            this.BTN_Refresh.Click += new System.EventHandler(this.BTN_Refresh_Click);
            // 
            // Timer1
            // 
            this.Timer1.Tick += new System.EventHandler(this.Timer1_Tick);
            // 
            // BTN_Save
            // 
            this.BTN_Save.Enabled = false;
            this.BTN_Save.Location = new System.Drawing.Point(239, 392);
            this.BTN_Save.Name = "BTN_Save";
            this.BTN_Save.Size = new System.Drawing.Size(74, 24);
            this.BTN_Save.TabIndex = 6;
            this.BTN_Save.Text = "Save to File";
            this.BTN_Save.Click += new System.EventHandler(this.BTN_Save_Click);
            // 
            // BTN_NewFolder
            // 
            this.BTN_NewFolder.Enabled = false;
            this.BTN_NewFolder.Location = new System.Drawing.Point(85, 392);
            this.BTN_NewFolder.Name = "BTN_NewFolder";
            this.BTN_NewFolder.Size = new System.Drawing.Size(74, 24);
            this.BTN_NewFolder.TabIndex = 7;
            this.BTN_NewFolder.Text = "New folder";
            this.BTN_NewFolder.Click += new System.EventHandler(this.BTN_NewFolder_Click);
            // 
            // buttonNotifications
            // 
            this.buttonNotifications.Location = new System.Drawing.Point(316, 392);
            this.buttonNotifications.Name = "buttonNotifications";
            this.buttonNotifications.Size = new System.Drawing.Size(74, 24);
            this.buttonNotifications.TabIndex = 8;
            this.buttonNotifications.Text = "Notifications";
            this.buttonNotifications.Click += new System.EventHandler(this.buttonNotifications_Click);
            // 
            // pictureBox1
            // 
            this.pictureBox1.Location = new System.Drawing.Point(553, 11);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(100, 50);
            this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
            this.pictureBox1.TabIndex = 9;
            this.pictureBox1.TabStop = false;
            // 
            // PIMNavigator
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(552, 422);
            this.Controls.Add(this.pictureBox1);
            this.Controls.Add(this.buttonNotifications);
            this.Controls.Add(this.BTN_NewFolder);
            this.Controls.Add(this.BTN_Save);
            this.Controls.Add(this.BTN_Refresh);
            this.Controls.Add(this.BTN_Delete);
            this.Controls.Add(this.BTN_New);
            this.Controls.Add(this.BTN_Close);
            this.Controls.Add(this.LVW_ItemList);
            this.Controls.Add(this.TVW_Navigator);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.Name = "PIMNavigator";
            this.Text = "PIMNavigator";
            this.Load += new System.EventHandler(this.PIMNavigator_Load);
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        //===================================================================
        // IsEmptyPIMDate
        // 
        // Tests CA_DATA_DATE is empty
        // 
        //===================================================================
        private bool IsEmptyPIMDate(CAContentAccess.CADataDefinitions.CA_DATA_DATE pimDate)
        {
            if (pimDate.bDay == 0 & pimDate.lTimeZoneBias == 0 & pimDate.bHour == 0 & pimDate.bMinute == 0 & pimDate.bMonth == 0 & pimDate.bSecond == 0 & pimDate.lBias == 0 & pimDate.wYear == 0)
            {
                return true;
            }
            return false;
        }

        //===================================================================
        // ConvertPIMDataDate
        // 
        // Converts CA_DATA_DATE to Date
        // 
        //===================================================================
        private System.DateTime ConvertPIMDataDate(CAContentAccess.CADataDefinitions.CA_DATA_DATE pimDate)
        {
            if (IsEmptyPIMDate(pimDate))
            {
                System.DateTime emptyDate = new DateTime();
                return emptyDate;
            }
            System.DateTime dateReturn = new System.DateTime(System.Convert.ToInt32(pimDate.wYear), pimDate.bMonth, pimDate.bDay, pimDate.bHour, pimDate.bMinute, pimDate.bSecond, DateTimeKind.Utc);
            if ((pimDate.lBias != 0) | (pimDate.lTimeZoneBias != 0))
            {
                // Implicit conversion
                dateReturn = dateReturn.AddMinutes(pimDate.lTimeZoneBias);
                dateReturn = dateReturn.AddMinutes(pimDate.lBias);
            }
            else
            {
                // UTC time => local
                dateReturn = dateReturn.ToLocalTime();
            }
            return dateReturn;
        }

        //===================================================================
        // GetEmptyPIMDate
        // 
        // Gets empty CA_DATA_DATE
        // 
        //===================================================================
        private void GetEmptyPIMDate(ref CAContentAccess.CADataDefinitions.CA_DATA_DATE pimDate)
        {
            pimDate.iSize = Marshal.SizeOf(pimDate);
            pimDate.bDay = 0;
            pimDate.lBias = 0;
            pimDate.bHour = 0;
            pimDate.bMinute = 0;
            pimDate.bMonth = 0;
            pimDate.bSecond = 0;
            pimDate.lTimeZoneBias = 0;
            pimDate.wYear = 0;
        }

        //===================================================================
        // GetCurrentPIMDate
        // 
        // Gets current local date/time in CA_DATA_DATE format
        // 
        //===================================================================
        private void GetCurrentPIMDate(ref CAContentAccess.CADataDefinitions.CA_DATA_DATE pimDate)
        {
            System.DateTime dateCurrent = System.DateTime.Now;
            pimDate.iSize = Marshal.SizeOf(pimDate);
            pimDate.wYear = (ushort)dateCurrent.Year;
            pimDate.bMonth = (byte)dateCurrent.Month;
            pimDate.bDay = (byte)dateCurrent.Day;
            pimDate.bHour = (byte)dateCurrent.Hour;
            pimDate.bMinute = (byte)dateCurrent.Minute;
            pimDate.bSecond = (byte)dateCurrent.Second;
        }

        //===================================================================
        // ConvertToPIMDate
        // 
        // Converts local date/time to CA_DATA_DATE format
        // 
        //===================================================================
        private void ConvertToPIMDate(System.DateTime dateCurrent, ref CAContentAccess.CADataDefinitions.CA_DATA_DATE pimDate)
        {
            dateCurrent = System.TimeZone.CurrentTimeZone.ToUniversalTime(dateCurrent);
            pimDate.iSize = Marshal.SizeOf(pimDate);
            pimDate.wYear = (ushort)dateCurrent.Year;
            pimDate.bMonth = (byte)dateCurrent.Month;
            pimDate.bDay = (byte)dateCurrent.Day;
            pimDate.bHour = (byte)dateCurrent.Hour;
            pimDate.bMinute = (byte)dateCurrent.Minute;
            pimDate.bSecond = (byte)dateCurrent.Second;
            // Calculate TimeZone Bias
            if (System.TimeZone.CurrentTimeZone.IsDaylightSavingTime(dateCurrent))
            {
                pimDate.lBias = 60;
            }
            else
            {
                pimDate.lBias = 0;
            }
            System.TimeSpan timeZone;
            timeZone = System.TimeZone.CurrentTimeZone.GetUtcOffset(dateCurrent);
            pimDate.lTimeZoneBias = (int)timeZone.TotalMinutes - pimDate.lBias;
        }

        //===================================================================
        // PIMFieldType2String
        // 
        // Converts PIM field type values to string
        // 
        //===================================================================
        private string PIMFieldType2String(CAContentAccess.CADataDefinitions.CA_DATA_ITEM pimData)
        {
            string functionReturnValue = null;
            if (pimData.iFieldType == CADataDefinitions.CA_FIELD_TYPE_CONTACT_PI)
            {
                functionReturnValue = "PI";
                //Personal information
            }
            else if (pimData.iFieldType == CADataDefinitions.CA_FIELD_TYPE_CONTACT_NUMBER)
            {
                functionReturnValue = "Number";
            }
            else if (pimData.iFieldType == CADataDefinitions.CA_FIELD_TYPE_CONTACT_ADDRESS)
            {
                functionReturnValue = "Address";
            }
            else if (pimData.iFieldType == CADataDefinitions.CA_FIELD_TYPE_CONTACT_GENERAL)
            {
                functionReturnValue = "";
                // General information
            }
            else if (pimData.iFieldType == CADataDefinitions.CA_FIELD_TYPE_CALENDAR)
            {
                functionReturnValue = "";
                // Calendar item
            }
            else
            {
                functionReturnValue = "Unknown field type";
                // shouldn't occur
            }
            if (functionReturnValue.Length > 0)
            {
                functionReturnValue += ", ";
            }
            // Personal information
            if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_NAME)
            {
                functionReturnValue += "name";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_FN)
            {
                functionReturnValue += "first name";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_MN)
            {
                functionReturnValue += "middle name";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_LN)
            {
                functionReturnValue += "last name";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_TITLE)
            {
                functionReturnValue += "title";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_SUFFIX)
            {
                functionReturnValue += "suffix";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_COMPANY)
            {
                functionReturnValue += "company";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_JOB_TITLE)
            {
                functionReturnValue += "job title";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_BIRTHDAY)
            {
                functionReturnValue += "birthday";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_PICTURE)
            {
                functionReturnValue += "picture";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_NICKNAME)
            {
                functionReturnValue += "nickname";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_FORMAL_NAME)
            {
                functionReturnValue += "formal name";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_GIVEN_NAME_PRONUNCIATION)
            {
                functionReturnValue += "given name pronunciation";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_FAMILY_NAME_PRONUNCIATION)
            {
                functionReturnValue += "family name pronunciation";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_COMPANY_NAME_PRONUNCIATION)
            {
                functionReturnValue += "company name pronunciation";
            }
            // Numbers
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_TEL)
            {
                functionReturnValue += "telephone";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_TEL_HOME)
            {
                functionReturnValue += "home";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_TEL_WORK)
            {
                functionReturnValue += "work";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_TEL_PREF)
            {
                functionReturnValue += "preferred";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_TEL_CAR)
            {
                functionReturnValue += "car";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_TEL_DATA)
            {
                functionReturnValue += "data";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_MOBILE)
            {
                functionReturnValue += "mobile";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_MOBILE_HOME)
            {
                functionReturnValue += "mobile (home)";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_MOBILE_WORK)
            {
                functionReturnValue += "mobile (work)";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_PAGER)
            {
                functionReturnValue += "pager";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_FAX)
            {
                functionReturnValue += "fax";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_FAX_HOME)
            {
                functionReturnValue += "fax (home)";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_FAX_WORK)
            {
                functionReturnValue += "fax (work)";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_VIDEO)
            {
                functionReturnValue += "video";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_VIDEO_HOME)
            {
                functionReturnValue += "video (home)";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_VIDEO_WORK)
            {
                functionReturnValue += "work (work)";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_VOIP)
            {
                functionReturnValue += "voip";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_VOIP_HOME)
            {
                functionReturnValue += "voip (home)";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_VOIP_WORK)
            {
                functionReturnValue += "voip (work)";
            }
            // Addresses
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_POSTAL)
            {
                functionReturnValue += "postal";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_POSTAL_BUSINESS)
            {
                functionReturnValue += "business";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_POSTAL_PRIVATE)
            {
                functionReturnValue += "private";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_EMAIL)
            {
                functionReturnValue += "email";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_EMAIL_HOME)
            {
                functionReturnValue += "email (home)";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_EMAIL_WORK)
            {
                functionReturnValue += "email (work)";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_WEB)
            {
                functionReturnValue += "web";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_WEB_HOME)
            {
                functionReturnValue += "web (home)";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_WEB_WORK)
            {
                functionReturnValue += "web (work)";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_PTT)
            {
                functionReturnValue += "PTT";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_SIP_FOR_VIDEO)
            {
                functionReturnValue += "SIP for video";
            }
            // General fields
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_NOTE)
            {
                functionReturnValue += "Note";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_DTMF)
            {
                functionReturnValue += "DTMF";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_UID)
            {
                functionReturnValue += "UID";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_WIRELESS_VILLAGE)
            {
                functionReturnValue += "wireless village";
            }
            // Calendar sub types
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_DESCRIPTION)
            {
                functionReturnValue += "Description";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_LOCATION)
            {
                functionReturnValue += "Location";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_ITEM_DATA)
            {
                functionReturnValue += "";
                // "Generic Item data"
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_TODO_PRIORITY)
            {
                functionReturnValue += "todo prior.";
            }
            else if (pimData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_TODO_STATUS)
            {
                functionReturnValue += "todo status";
            }
            else
            {
                functionReturnValue += "unknown field sub type";
                // shouldn't occur
            }
            return functionReturnValue;
        }

        //===================================================================
        // PIMMessageStatus2String
        // 
        // Converts PIM message status values to string
        // 
        //===================================================================
        private string PIMMessageStatus2String(int iInfo)
        {
            string functionReturnValue = null;
            int iStatus = CADataDefinitions.CA_GET_MESSAGE_STATUS(iInfo);
            if (iStatus == CADataDefinitions.CA_MESSAGE_STATUS_SENT)
            {
                functionReturnValue = "Sent";
            }
            else if (iStatus == CADataDefinitions.CA_MESSAGE_STATUS_UNREAD)
            {
                functionReturnValue = "Hasn't been read";
            }
            else if (iStatus == CADataDefinitions.CA_MESSAGE_STATUS_READ)
            {
                functionReturnValue = "Has been read";
            }
            else if (iStatus == CADataDefinitions.CA_MESSAGE_STATUS_DRAFT)
            {
                functionReturnValue = "Draft";
            }
            else if (iStatus == CADataDefinitions.CA_MESSAGE_STATUS_PENDING)
            {
                functionReturnValue = "Pending";
            }
            else if (iStatus == CADataDefinitions.CA_MESSAGE_STATUS_DELIVERED)
            {
                functionReturnValue = "Delivered";
            }
            else if (iStatus == CADataDefinitions.CA_MESSAGE_STATUS_SENDING)
            {
                functionReturnValue = "Being sent";
            }
            else
            {
                functionReturnValue = "Unknown";
            }
            return functionReturnValue;
        }

        //===================================================================
        // PIMCalendarRecurrence2String
        // 
        // Converts PIM Calendar recurrence values to string
        // 
        //===================================================================
        private string PIMCalendarRecurrence2String(int iRecurrence)
        {
            string functionReturnValue = null;
            int IRec = CADataDefinitions.CA_GET_RECURRENCE(iRecurrence);
            if (IRec == CADataDefinitions.CA_CALENDAR_RECURRENCE_NONE)
            {
                functionReturnValue = "None";
            }
            else if (IRec == CADataDefinitions.CA_CALENDAR_RECURRENCE_DAILY)
            {
                functionReturnValue = "Daily";
            }
            else if (IRec == CADataDefinitions.CA_CALENDAR_RECURRENCE_WEEKLY)
            {
                functionReturnValue = "Weekly";
            }
            else if (IRec == CADataDefinitions.CA_CALENDAR_RECURRENCE_MONTHLY)
            {
                functionReturnValue = "Monthly";
            }
            else if (IRec == CADataDefinitions.CA_CALENDAR_RECURRENCE_YEARLY)
            {
                functionReturnValue = "Yearly";
            }
            else
            {
                functionReturnValue = "Unknown (" + iRecurrence.ToString() + ")";
            }
            if (IRec != CADataDefinitions.CA_CALENDAR_RECURRENCE_NONE)
            {
                IRec = CADataDefinitions.CA_GET_RECURRENCE_INTERVAL(iRecurrence);
                functionReturnValue += ", interval " + IRec.ToString();
            }
            return functionReturnValue;
        }

        //===================================================================
        // PIMCalendarTodoPriority2String
        // 
        // Converts PIM Calendar TODO priority values to string
        // 
        //===================================================================
        private string PIMCalendarTodoPriority2String(int iTodoPriority)
        {
            string functionReturnValue = null;
            if (iTodoPriority == CADataDefinitions.CA_CALENDAR_TODO_PRIORITY_HIGH)
            {
                functionReturnValue = "High";
            }
            else if (iTodoPriority == CADataDefinitions.CA_CALENDAR_TODO_PRIORITY_NORMAL)
            {
                functionReturnValue = "Normal";
            }
            else if (iTodoPriority == CADataDefinitions.CA_CALENDAR_TODO_PRIORITY_LOW)
            {
                functionReturnValue = "Low";
            }
            else
            {
                functionReturnValue = "Unknown (" + iTodoPriority.ToString() + ")";
            }
            return functionReturnValue;
        }

        //===================================================================
        // PIMCalendarTodoStatus2String
        // 
        // Converts PIM Calendar TODO status values to string
        // 
        //===================================================================
        private string PIMCalendarTodoStatus2String(int iTodoStatus)
        {
            string functionReturnValue = null;
            if (iTodoStatus == CADataDefinitions.CA_CALENDAR_TODO_STATUS_NEEDS_ACTION)
            {
                functionReturnValue = "Needs action";
            }
            else if (iTodoStatus == CADataDefinitions.CA_CALENDAR_TODO_STATUS_COMPLETED)
            {
                functionReturnValue = "Completed";
            }
            else
            {
                functionReturnValue = "Unknown (" + iTodoStatus + ")";
            }
            return functionReturnValue;
        }

        //===================================================================
        // DeviceNotifyCallback
        //
        // Callback function for device connection notifications
        //
        //===================================================================
        public int DeviceNotifyCallback( 
            int iStatus, 
            [MarshalAs(UnmanagedType.LPWStr)] string pstrSerialNumber)
        {
            // Refresh tree view after next timer tick
            bRefresh = true;
            return PCCSErrors.CONA_OK;
        }

        //===================================================================
        // CloseContactsConnection
        //
        // Close PIM connection to contacts folder
        //
        //===================================================================
        private int CloseContactsConnection()
        {
            int iRet = PCCSErrors.CONA_OK;
            if (m_hContacts != 0)
            {
                // Unregister CallBack
                int iResult = DAContentAccess.CARegisterNotifyCallback(m_hContacts, PCCSTypeDefinitions.API_UNREGISTER, pCANotifyCallBack);

                // Close PIM connection
                iRet = DAContentAccess.DACloseCA(m_hContacts);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("DACloseCA", iRet);
                }
                m_hContacts = 0;
            }
            return iRet;
        }

        //===================================================================
        // CheckContactsConnection
        //
        // Check PIM connection to contacts folder and open it if needed
        //
        //===================================================================
        private int CheckContactsConnection(string strSerialNumber)
        {
            int iRet = PCCSErrors.CONA_OK;
            if (m_strCurrentContactsSerialNumber != strSerialNumber)
            {
                // Device has changed, close previous connection
                CloseContactsConnection();
                m_strCurrentContactsSerialNumber = strSerialNumber;
            }
            if (m_hContacts == 0)
            {
                // No PIM connection, open it
                IntPtr pstrSerialNumber = Marshal.StringToCoTaskMemUni(strSerialNumber);
                // CONAAllocString(strSerialNumber)
                int iMedia = CONADefinitions.API_MEDIA_ALL;
                int iTarget = CADataDefinitions.CA_TARGET_CONTACTS;
                iRet = DAContentAccess.DAOpenCA(pstrSerialNumber, ref iMedia, iTarget, ref m_hContacts);
                if (iRet != PCCSErrors.CONA_OK & iRet != PCCSErrors.ECONA_NOT_SUPPORTED_DEVICE)
                {
                    PCCAPIUtils.ShowErrorMessage("DAOpenCA", iRet);
                }

                Marshal.FreeCoTaskMem(pstrSerialNumber);
                // Register device notification callback function
                if (m_hContacts != 0)
                {
                    int iResult = DAContentAccess.CARegisterNotifyCallback(m_hContacts, PCCSTypeDefinitions.API_REGISTER, pCANotifyCallBack);
                    if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterNotifyCallback", iResult);
                }
            }
            return iRet;
        }

        //===================================================================
        // CloseSMSConnection
        //
        // Close PIM connection to SMS folders
        //
        //===================================================================
        private int CloseSMSConnection()
        {
            int iRet = PCCSErrors.CONA_OK;
            if (m_hSMS != 0)
            {
                // Unregister CallBack
                int iResult = DAContentAccess.CARegisterNotifyCallback(m_hSMS, PCCSTypeDefinitions.API_UNREGISTER, pCANotifyCallBack);
                if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CONARegisterNotifyCallback", iResult);

                // Close PIM connection
                iRet = DAContentAccess.DACloseCA(m_hSMS);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("DACloseCA", iRet);
                }
                m_hSMS = 0;
            }
            return iRet;
        }

        //===================================================================
        // CheckSMSConnection
        //
        // Check PIM connection to SMS folders and open it if needed
        //
        //===================================================================
        private int CheckSMSConnection(string strSerialNumber)
        {
            int iRet = PCCSErrors.CONA_OK;
            if (m_strCurrentSMSSerialNumber != strSerialNumber)
            {
                // Device has changed, close previous connection
                CloseSMSConnection();
                m_strCurrentSMSSerialNumber = strSerialNumber;
            }
            if (m_hSMS == 0)
            {
                // No PIM connection, open it
                IntPtr pstrSerialNumber = Marshal.StringToCoTaskMemUni(strSerialNumber);
                int iMedia = CONADefinitions.API_MEDIA_ALL;
                int iTarget = CADataDefinitions.CA_TARGET_SMS_MESSAGES;
                iRet = DAContentAccess.DAOpenCA(pstrSerialNumber,ref iMedia, iTarget, ref m_hSMS);
                if (iRet != PCCSErrors.CONA_OK & iRet != PCCSErrors.ECONA_NOT_SUPPORTED_DEVICE)
                {
                    PCCAPIUtils.ShowErrorMessage("DAOpenCA", iRet);
                }
                Marshal.FreeCoTaskMem(pstrSerialNumber);

                // Register device notification callback function
                if (m_hSMS != 0)
                {
                    int iResult = DAContentAccess.CARegisterNotifyCallback(m_hSMS, PCCSTypeDefinitions.API_REGISTER, pCANotifyCallBack);
                    if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterNotifyCallback", iResult);

                }
            }
            return iRet;
        }

        //===================================================================
        // CloseMMSConnection
        //
        // Close PIM connection to MMS folders
        //
        //===================================================================
        private int CloseMMSConnection()
        {
            int iRet = PCCSErrors.CONA_OK;
            if (m_hMMS != 0)
            {
                // Unregister CallBack
                int iResult = DAContentAccess.CARegisterNotifyCallback(m_hSMS, PCCSTypeDefinitions.API_UNREGISTER, pCANotifyCallBack);
                // Close PIM connection
                iRet = DAContentAccess.DACloseCA(m_hMMS);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("DACloseCA", iRet);
                }
                m_hMMS = 0;
            }
            return iRet;
        }

        //===================================================================
        // CheckMMSConnection
        //
        // Check PIM connection to MMS folders and open it if needed
        //
        //===================================================================
        private int CheckMMSConnection(string strSerialNumber)
        {
            int iRet = PCCSErrors.CONA_OK;
            if (m_strCurrentMMSSerialNumber != strSerialNumber)
            {
                // Device has changed, close previous connection
                CloseMMSConnection();
                m_strCurrentMMSSerialNumber = strSerialNumber;
            }
            if (m_hMMS == 0)
            {
                // No PIM connection, open it
                IntPtr pstrSerialNumber = Marshal.StringToCoTaskMemUni(strSerialNumber);
                int iMedia = CONADefinitions.API_MEDIA_ALL;
                int iTarget = CADataDefinitions.CA_TARGET_MMS_MESSAGES;
                iRet = DAContentAccess.DAOpenCA(pstrSerialNumber,ref iMedia, iTarget, ref m_hMMS);
                if (iRet != PCCSErrors.CONA_OK & iRet != PCCSErrors.ECONA_NOT_SUPPORTED_DEVICE)
                {
                    PCCAPIUtils.ShowErrorMessage("DAOpenCA", iRet);
                }
                Marshal.FreeCoTaskMem(pstrSerialNumber);
                // Register device notification callback function
                if (m_hMMS != 0)
                {
                    int iResult = DAContentAccess.CARegisterNotifyCallback(m_hSMS, PCCSTypeDefinitions.API_REGISTER, pCANotifyCallBack);
                    if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterNotifyCallback", iResult);

                }
            }
            return iRet;
        }

        //===================================================================
        // CloseCalendarConnection
        //
        // Close PIM connection to Calendar folders
        //
        //===================================================================
        private int CloseCalendarConnection()
        {
            int iRet = PCCSErrors.CONA_OK;
            if (m_hCalendar != 0)
            {
                // Unregister CallBack
                int iResult = DAContentAccess.CARegisterNotifyCallback(m_hCalendar, PCCSTypeDefinitions.API_UNREGISTER, pCANotifyCallBack);

                // Close PIM connection
                iRet = DAContentAccess.DACloseCA(m_hCalendar);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("DACloseCA", iRet);
                }
                m_hCalendar = 0;
            }
            return iRet;
        }

        //===================================================================
        // CheckCalendarConnection
        //
        // Check PIM connection to Calendar folders and open it if needed
        //
        //===================================================================
        private int CheckCalendarConnection(string strSerialNumber)
        {
            int iRet = PCCSErrors.CONA_OK;
            if (m_strCurrentCalendarSerialNumber != strSerialNumber)
            {
                // Device has changed, close previous connection
                CloseCalendarConnection();
                m_strCurrentCalendarSerialNumber = strSerialNumber;
            }
            if (m_hCalendar == 0)
            {
                // No PIM connection, open it
                IntPtr pstrSerialNumber = Marshal.StringToCoTaskMemUni(strSerialNumber);
                int iMedia = CONADefinitions.API_MEDIA_ALL;
                int iTarget = CADataDefinitions.CA_TARGET_CALENDAR;
                iRet = DAContentAccess.DAOpenCA(pstrSerialNumber,ref iMedia, iTarget, ref  m_hCalendar);
                if (iRet != PCCSErrors.CONA_OK & iRet != PCCSErrors.ECONA_NOT_SUPPORTED_DEVICE)
                {
                    PCCAPIUtils.ShowErrorMessage("DAOpenCA", iRet);
                }
                Marshal.FreeCoTaskMem(pstrSerialNumber);

                // Register device notification callback function
                if (m_hCalendar != 0)
                {
                    int iResult = DAContentAccess.CARegisterNotifyCallback(m_hCalendar, PCCSTypeDefinitions.API_REGISTER, pCANotifyCallBack);
                    if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterNotifyCallback", iResult);

                }
            }
            return iRet;
        }

        //===================================================================
        // CloseBookmarkConnection
        //
        // Close PIM connection to Bookmark folders
        //
        //===================================================================
        private int CloseBookmarkConnection()
        {
            int iRet = PCCSErrors.CONA_OK;
            if (m_hBookmark != 0)
            {
                // Unregister CallBack
                int iResult = DAContentAccess.CARegisterNotifyCallback(m_hBookmark, PCCSTypeDefinitions.API_UNREGISTER, pCANotifyCallBack);

                // Close PIM connection
                iRet = DAContentAccess.DACloseCA(m_hBookmark);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("DACloseCA", iRet);
                }
                m_hBookmark = 0;
            }
            return iRet;
        }

        //===================================================================
        // CheckBookmarkConnection
        //
        // Check PIM connection to Calendar folders and open it if needed
        //
        //===================================================================
        private int CheckBookmarkConnection(string strSerialNumber)
        {
            int iRet = PCCSErrors.CONA_OK;
            if (m_strCurrentBookmarkSerialNumber != strSerialNumber)
            {
                // Device has changed, close previous connection
                CloseBookmarkConnection();
                m_strCurrentBookmarkSerialNumber = strSerialNumber;
            }
            if (m_hBookmark == 0)
            {
                // No PIM connection, open it
                IntPtr pstrSerialNumber = Marshal.StringToCoTaskMemUni(strSerialNumber);
                int iMedia = CONADefinitions.API_MEDIA_ALL;
                int iTarget = CADataDefinitions.CA_TARGET_BOOKMARKS;
                iRet = DAContentAccess.DAOpenCA(pstrSerialNumber, ref iMedia, iTarget, ref m_hBookmark);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    if (iRet == PCCSErrors.ECONA_NOT_SUPPORTED_DEVICE)
                    {
                        MessageBox.Show("Phone does not support bookmarks", "Phone Navigator");
                    }
                    else
                    {
                        PCCAPIUtils.ShowErrorMessage("DAOpenCA", iRet);
                    }
                }
                Marshal.FreeCoTaskMem(pstrSerialNumber);

                // Register CA notification callback function
                if (m_hBookmark != 0)
                {
                    int iResult = DAContentAccess.CARegisterNotifyCallback(m_hBookmark, PCCSTypeDefinitions.API_REGISTER, pCANotifyCallBack);
                    if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterNotifyCallback", iResult);
                }
            }
            return iRet;
        }

        //===================================================================
        // AddFolder
        //
        // Adds folder to tree view and calls recursively itself for subfolders.
        //
        //===================================================================
        private void AddFolder(string strRootFolder, CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo, System.Windows.Forms.TreeNode parentItem, int iIconFolderIndex, int iIconItemIndex)
        {
            //If folderInfo Is Nothing Then
            //Return
            //End If
            // Insert folder item in tree view
            string strFolderName;
            if (folderInfo.pstrName == "\\")
            {
                strFolderName = strRootFolder;
            }
            else
            {
                strFolderName = folderInfo.pstrName;
            }
            // Insert target folder item in tree view
            System.Windows.Forms.TreeNode itemY = new System.Windows.Forms.TreeNode();
            itemY.Text = strFolderName;
            itemY.ImageIndex = iIconFolderIndex;
            itemY.SelectedImageIndex = iIconFolderIndex;
            itemY.Tag = MapCFIToCAFolderInfo(folderInfo);
            parentItem.Nodes.Add(itemY);
            // Add dummy item to get '+' showed.
            System.Windows.Forms.TreeNode itemZ = new System.Windows.Forms.TreeNode();
            itemZ.Text = "";
            itemZ.ImageIndex = iIconItemIndex;
            itemZ.SelectedImageIndex = iIconItemIndex;
            itemZ.Tag = null;
            itemY.Nodes.Add(itemZ);
            int i;

            for (i = 0; i < folderInfo.iSubFolderCount; i++)
            {
                // Recursive call for adding subfolders.
                CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO subFolderInfo = new CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO();
                subFolderInfo.iSize = Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO));

                // Calculate beginning of CONAPI_DEVICE structure of item 'i'
                Int64 iPtr = folderInfo.pSubFolders.ToInt64() + i * Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO));
                // Convert integer to pointer
                IntPtr ptr = new IntPtr(iPtr);
                // Copy data from buffer
                subFolderInfo = (CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO)Marshal.PtrToStructure(ptr, typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO));

                AddFolder(strRootFolder, subFolderInfo, itemY, iIconFolderIndex, iIconItemIndex);
            }

        }

        //===================================================================
        // GetContactsFolder
        //
        // Gets Contacts folder info and creates folder in tree view
        //
        //===================================================================
        private void GetContactsFolder(string strSerialNumber, System.Windows.Forms.TreeNode parentItem)
        {
            // Check PIM connection to contacts folder and open it if needed
            int iRet = CheckContactsConnection(strSerialNumber);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Get contacts folder info
                CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;
                folderInfo = new CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO();
                folderInfo.iSize = Marshal.SizeOf(folderInfo);
                IntPtr bufItem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO)));
                Marshal.StructureToPtr(folderInfo, bufItem, false);
                iRet = DAContentAccess.CAGetFolderInfo(m_hContacts, bufItem);
                if (iRet == PCCSErrors.CONA_OK)
                {
                    folderInfo = (CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO)Marshal.PtrToStructure(bufItem, typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO));
                    AddFolder("Contacts", folderInfo, parentItem, m_iIconContactsIndex, m_iIconContactIndex);
                }
                else
                {
                    PCCAPIUtils.ShowErrorMessage("CAGetFolderInfo", iRet);
                }
                int iResult = DAContentAccess.CAFreeFolderInfoStructure(bufItem);
                if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CAFreeFolderInfoStructure", iResult);
                Marshal.FreeHGlobal(bufItem);
            }
        }

        //===================================================================
        // GetSMSFolders
        //
        // Gets SMS folder info and creates folders in tree view
        //
        //===================================================================
        private void GetSMSFolders(string strSerialNumber, System.Windows.Forms.TreeNode parentItem)
        {
            // Check PIM connection to SMS folders and open it if needed
            int iRet = CheckSMSConnection(strSerialNumber);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Get SMS folder info
                CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;
                folderInfo = new CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO();
                folderInfo.iSize = Marshal.SizeOf(folderInfo);
                IntPtr bufItem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO)));
                Marshal.StructureToPtr(folderInfo, bufItem, false);
                iRet = DAContentAccess.CAGetFolderInfo(m_hSMS, bufItem);
                if (iRet == PCCSErrors.CONA_OK)
                {
                    folderInfo = (CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO)Marshal.PtrToStructure(bufItem, typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO));
                    AddFolder("SMS Messages", folderInfo, parentItem, m_iIconSMSMessagesIndex, m_iIconSMSIndex);
                }
                else
                {
                    PCCAPIUtils.ShowErrorMessage("CAGetFolderInfo", iRet);
                }
                int iResult = DAContentAccess.CAFreeFolderInfoStructure(bufItem);
                if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CAFreeFolderInfoStructure", iResult);
                Marshal.FreeHGlobal(bufItem);
            }
        }

        //===================================================================
        // GetMMSFolders
        //
        // Gets SMS folder info and creates folders in tree view
        //
        //===================================================================
        private void GetMMSFolders(string strSerialNumber, System.Windows.Forms.TreeNode parentItem)
        {
            // Check PIM connection to MMS folders and open it if needed
            int iRet = CheckMMSConnection(strSerialNumber);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Get MMS folder info
                CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;
                folderInfo = new CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO();
                folderInfo.iSize = Marshal.SizeOf(folderInfo);
                IntPtr bufItem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO)));
                Marshal.StructureToPtr(folderInfo, bufItem, false);
                iRet = DAContentAccess.CAGetFolderInfo(m_hMMS, bufItem);
                if (iRet == PCCSErrors.CONA_OK)
                {
                    folderInfo = (CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO)Marshal.PtrToStructure(bufItem, typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO));
                    AddFolder("MMS Messages", folderInfo, parentItem, m_iIconMMSMessagesIndex, m_iIconMMSIndex);
                }
                else
                {
                    PCCAPIUtils.ShowErrorMessage("CAGetFolderInfo", iRet);
                }
                int iResult = DAContentAccess.CAFreeFolderInfoStructure(bufItem);
                if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CAFreeFolderInfoStructure", iResult);
                Marshal.FreeHGlobal(bufItem);
            }
        }

        //===================================================================
        // GetCalendarFolder
        //
        // Gets Calendar folder info and creates folder in tree view
        //
        //===================================================================
        private void GetCalendarFolder(string strSerialNumber, System.Windows.Forms.TreeNode parentItem)
        {
            // Check PIM connection to Calendar folders and open it if needed
            int iRet = CheckCalendarConnection(strSerialNumber);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Get Calendar folder info
                CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;
                folderInfo = new CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO();
                folderInfo.iSize = Marshal.SizeOf(folderInfo);
                IntPtr bufItem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO)));
                Marshal.StructureToPtr(folderInfo, bufItem, false);
                iRet = DAContentAccess.CAGetFolderInfo(m_hCalendar, bufItem);
                if (iRet == PCCSErrors.CONA_OK)
                {
                    folderInfo = (CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO)Marshal.PtrToStructure(bufItem, typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO));
                    AddFolder("Calendar", folderInfo, parentItem, m_iIconCalendarIndex, m_iIconCalendarItemIndex);
                }
                else
                {
                    PCCAPIUtils.ShowErrorMessage("CAGetFolderInfo", iRet);
                }
                int iResult = DAContentAccess.CAFreeFolderInfoStructure(bufItem);
                if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CAFreeFolderInfoStructure", iResult);
                Marshal.FreeHGlobal(bufItem);
            }
        }

        //===================================================================
        // GetBookmarkFolder
        //
        // Gets Bookmarks folder info and creates folder in tree view
        //
        //===================================================================
        private void GetBookmarkFolder(string strSerialNumber, System.Windows.Forms.TreeNode parentItem)
        {
            // Check PIM connection to Calendar folders and open it if needed
            int iRet = CheckBookmarkConnection(strSerialNumber);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Get Calendar folder info
                CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;
                folderInfo = new CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO();
                folderInfo.iSize = Marshal.SizeOf(folderInfo);
                IntPtr bufItem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO)));
                Marshal.StructureToPtr(folderInfo, bufItem, false);
                iRet = DAContentAccess.CAGetFolderInfo(m_hBookmark, bufItem);
                if (iRet == PCCSErrors.CONA_OK)
                {
                    folderInfo = (CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO)Marshal.PtrToStructure(bufItem, typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO));
                    AddFolder("Bookmarks", folderInfo, parentItem, m_iIconBookmarkIndex, m_iIconBookmarkItemIndex);
                }
                else
                {
                    PCCAPIUtils.ShowErrorMessage("CAGetFolderInfo", iRet);
                }
                int iResult = DAContentAccess.CAFreeFolderInfoStructure(bufItem);
                if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CAFreeFolderInfoStructure", iResult);
                Marshal.FreeHGlobal(bufItem);
            }
        }

        //===================================================================
        // ReadContact
        //
        // Reads contact from device
        //
        //===================================================================
        private int ReadContact(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID, ref CAContentAccess.CADataDefinitions.CA_DATA_CONTACT dataContact)
        {
            int hOperHandle=0;
            int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0, ref hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
            }
            dataContact.iSize = Marshal.SizeOf(dataContact);
            dataContact.bPICount = 0;
            dataContact.pPIFields = IntPtr.Zero;
            dataContact.bAddressCount = 0;
            dataContact.pAddressFields = IntPtr.Zero;
            dataContact.bNumberCount = 0;
            dataContact.pNumberFields = IntPtr.Zero;
            dataContact.bGeneralCount = 0;
            dataContact.pGeneralFields = IntPtr.Zero;
            // Allocate memory for buffers
            IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
            Marshal.StructureToPtr(UID, buffer, true);
            UID.iSize = Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID));
            m_pContactBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(dataContact));
            Marshal.StructureToPtr(dataContact, m_pContactBuffer, true);
            iRet = DAContentAccess.CAReadItem(hOperHandle, buffer, DAContentAccessDefinitions.CA_OPTION_USE_CACHE, CADataDefinitions.CA_DATA_FORMAT_STRUCT, m_pContactBuffer);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Copy data from buffer
                dataContact = (CAContentAccess.CADataDefinitions.CA_DATA_CONTACT)Marshal.PtrToStructure(m_pContactBuffer, typeof(CAContentAccess.CADataDefinitions.CA_DATA_CONTACT));
            }
            else
            {
                PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
                Marshal.FreeHGlobal(m_pContactBuffer);
                m_pContactBuffer = IntPtr.Zero;
            }
            Marshal.FreeHGlobal(buffer);
            int iResult = DAContentAccess.CAEndOperation(hOperHandle);
            if (iResult != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CAEndOperation", iResult);
            }
            return iRet;
        }

        //===================================================================
        // FreeContactData
        //
        // Frees allocated memory of Contact
        //
        //===================================================================
        private void FreeContactData()
        {
            // Free memory allocated by DA API
            int iRet = DAContentAccess.CAFreeItemData(m_hContacts, CADataDefinitions.CA_DATA_FORMAT_STRUCT, m_pContactBuffer);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iRet);
            Marshal.FreeHGlobal(m_pContactBuffer);
            m_pContactBuffer = IntPtr.Zero;
        }

        //===================================================================
        // GetContactDetails
        //
        // Read selected contact from phone and show details in list view.
        //
        //===================================================================
        private void GetContactDetails(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID)
        {
            // Read contact item data from device
            CAContentAccess.CADataDefinitions.CA_DATA_CONTACT dataContact = new CADataDefinitions.CA_DATA_CONTACT();
            int iRet = ReadContact(UID, ref dataContact);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Personal information
                int i;
                for (i = 0; i < dataContact.bPICount; i++)
                {
                    // Calculate beginning of CA_DATA_ITEM structure of item 'i'
                    Int64 iPtr = dataContact.pPIFields.ToInt64() + i * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                    // Convert integer to pointer
                    IntPtr ptr = new IntPtr(iPtr);
                    CAContentAccess.CADataDefinitions.CA_DATA_ITEM itemData;
                    itemData = (CAContentAccess.CADataDefinitions.CA_DATA_ITEM)Marshal.PtrToStructure(ptr, typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                    // Add item to list view
                    System.Windows.Forms.ListViewItem itemX = new System.Windows.Forms.ListViewItem();
                    itemX.Text = PIMFieldType2String(itemData);
                    LVW_ItemList.Items.Add(itemX);
                    if (itemData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_BIRTHDAY)
                    {
                        CADataDefinitions.CA_DATA_DATE bDate = new CADataDefinitions.CA_DATA_DATE();
                        bDate = (CADataDefinitions.CA_DATA_DATE)Marshal.PtrToStructure(itemData.pCustomData, typeof(CADataDefinitions.CA_DATA_DATE));
                        string strTmp = bDate.bDay.ToString() + "." + bDate.bDay.ToString() + "." +bDate.wYear.ToString(); 
                        itemX.SubItems.Add(strTmp);
                    }
                    else if (itemData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_PICTURE)
                    {
                        CAContentAccess.CADataDefinitions.CA_DATA_PICTURE dataPicture;
                        dataPicture = (CAContentAccess.CADataDefinitions.CA_DATA_PICTURE)Marshal.PtrToStructure(itemData.pCustomData, typeof(CAContentAccess.CADataDefinitions.CA_DATA_PICTURE));
                        byte[] bytes = new byte[dataPicture.iDataLen];
                        Marshal.Copy(dataPicture.pbData, bytes, 0, dataPicture.iDataLen);
                        // Write image data to temporary file
                        m_strFile = System.IO.Path.GetTempFileName();
                        System.IO.File.WriteAllBytes(m_strFile, bytes);
                        // Create image from file
                        pictureBox1.Image = System.Drawing.Image.FromFile(m_strFile);
                        System.Drawing.Size size1  = this.Size;
                        System.Drawing.Size size2 = pictureBox1.Size;
                        size1.Width = size1.Width + size2.Width + 15;
                        this.Size = size1;
                    }
                    else
                    {
                        itemX.SubItems.Add(Marshal.PtrToStringUni(itemData.pCustomData));
                    }
                }
                // Numbers
                for (i = 0; i < dataContact.bNumberCount; i++)
                {
                    // Calculate beginning of CA_DATA_ITEM structure of item 'i'
                    Int64 iPtr = dataContact.pNumberFields.ToInt64() + i * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                    // Convert integer to pointer
                    IntPtr ptr = new IntPtr(iPtr);
                    CAContentAccess.CADataDefinitions.CA_DATA_ITEM itemData;
                    itemData = (CAContentAccess.CADataDefinitions.CA_DATA_ITEM)Marshal.PtrToStructure(ptr, typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                    // Add item to list view
                    System.Windows.Forms.ListViewItem itemX = new System.Windows.Forms.ListViewItem();
                    itemX.Text = PIMFieldType2String(itemData);
                    LVW_ItemList.Items.Add(itemX);
                    itemX.SubItems.Add(Marshal.PtrToStringUni(itemData.pCustomData));
                }
                // Addresses
                for (i = 0; i < dataContact.bAddressCount; i++)
                {
                    // Calculate beginning of CA_DATA_ITEM structure of item 'i'
                    Int64 iPtr = dataContact.pAddressFields.ToInt64() + i * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                    // Convert integer to pointer
                    IntPtr ptr = new IntPtr(iPtr);
                    CAContentAccess.CADataDefinitions.CA_DATA_ITEM itemData;
                    itemData = (CAContentAccess.CADataDefinitions.CA_DATA_ITEM)Marshal.PtrToStructure(ptr, typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                    // Add item to list view
                    System.Windows.Forms.ListViewItem itemX = new System.Windows.Forms.ListViewItem();
                    itemX.Text = PIMFieldType2String(itemData);
                    LVW_ItemList.Items.Add(itemX);
                    if (itemData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_POSTAL | itemData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_POSTAL_BUSINESS | itemData.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_POSTAL_PRIVATE)
                    {
                        CADataDefinitions.CA_DATA_POSTAL_ADDRESS postal;
                        postal = (CADataDefinitions.CA_DATA_POSTAL_ADDRESS)Marshal.PtrToStructure(itemData.pCustomData, typeof(CADataDefinitions.CA_DATA_POSTAL_ADDRESS));
                        if ((postal.pstrPOBox != null))
                        {
                            System.Windows.Forms.ListViewItem item1 = new System.Windows.Forms.ListViewItem();
                            item1.Text = "    PO Box";
                            item1.SubItems.Add(postal.pstrPOBox);
                            LVW_ItemList.Items.Add(item1);
                        }
                        if ((postal.pstrStreet != null))
                        {
                            System.Windows.Forms.ListViewItem item1 = new System.Windows.Forms.ListViewItem();
                            item1.Text = "    Street";
                            item1.SubItems.Add(postal.pstrStreet);
                            LVW_ItemList.Items.Add(item1);
                        }
                        if ((postal.pstrPostalCode != null))
                        {
                            System.Windows.Forms.ListViewItem item1 = new System.Windows.Forms.ListViewItem();
                            item1.Text = "    Postal code";
                            item1.SubItems.Add(postal.pstrPostalCode);
                            LVW_ItemList.Items.Add(item1);
                        }
                        if ((postal.pstrCity != null))
                        {
                            System.Windows.Forms.ListViewItem item1 = new System.Windows.Forms.ListViewItem();
                            item1.Text = "    City";
                            item1.SubItems.Add(postal.pstrCity);
                            LVW_ItemList.Items.Add(item1);
                        }
                        if ((postal.pstrState != null))
                        {
                            System.Windows.Forms.ListViewItem item1 = new System.Windows.Forms.ListViewItem();
                            item1.Text = "    State";
                            item1.SubItems.Add(postal.pstrState);
                            LVW_ItemList.Items.Add(item1);
                        }
                        if ((postal.pstrCountry != null))
                        {
                            System.Windows.Forms.ListViewItem item1 = new System.Windows.Forms.ListViewItem();
                            item1.Text = "    Country";
                            item1.SubItems.Add(postal.pstrCountry);
                            LVW_ItemList.Items.Add(item1);
                        }
                        if ((postal.pstrExtendedData != null))
                        {
                            System.Windows.Forms.ListViewItem item1 = new System.Windows.Forms.ListViewItem();
                            item1.Text = "    Extended address information";
                            item1.SubItems.Add(postal.pstrExtendedData);
                            LVW_ItemList.Items.Add(item1);
                        }
                    }
                    else
                    {
                        itemX.SubItems.Add(Marshal.PtrToStringUni(itemData.pCustomData));
                    }
                }
                // General information
                for (i = 0; i < dataContact.bGeneralCount; i++)
                {
                    // Calculate beginning of CA_DATA_ITEM structure of item 'i'
                    Int64 iPtr = dataContact.pGeneralFields.ToInt64() + i * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                    // Convert integer to pointer
                    IntPtr ptr = new IntPtr(iPtr);
                    CAContentAccess.CADataDefinitions.CA_DATA_ITEM itemData;
                    itemData = (CAContentAccess.CADataDefinitions.CA_DATA_ITEM)Marshal.PtrToStructure(ptr, typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                    // Add item to list view
                    System.Windows.Forms.ListViewItem itemX = new System.Windows.Forms.ListViewItem();
                    itemX.Text = PIMFieldType2String(itemData);
                    LVW_ItemList.Items.Add(itemX);
                    itemX.SubItems.Add(Marshal.PtrToStringUni(itemData.pCustomData));
                }
                FreeContactData();
            }
        }

        //===================================================================
        // ReadCalendarItem
        //
        // Reads calendar item from device
        //
        //===================================================================
        private int ReadCalendarItem(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID, ref CAContentAccess.CADataDefinitions.CA_DATA_CALENDAR dataCalendar)
        {
            int hOperHandle=0;
            int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0, ref hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
            }
            dataCalendar.iSize = Marshal.SizeOf(dataCalendar);
            dataCalendar.bItemCount = 0;
            dataCalendar.iInfoField = 0;
            dataCalendar.iRecurrence = 0;
            dataCalendar.pDataItems = IntPtr.Zero;
            // Allocate memory for buffers
            IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
            Marshal.StructureToPtr(UID, buffer, true);
            m_pCalendarBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(dataCalendar));
            Marshal.StructureToPtr(dataCalendar, m_pCalendarBuffer, true);
            iRet = DAContentAccess.CAReadItem(hOperHandle, buffer, DAContentAccessDefinitions.CA_OPTION_USE_CACHE, CADataDefinitions.CA_DATA_FORMAT_STRUCT, m_pCalendarBuffer);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Copy data from buffer
                dataCalendar = (CAContentAccess.CADataDefinitions.CA_DATA_CALENDAR)Marshal.PtrToStructure(m_pCalendarBuffer, typeof(CAContentAccess.CADataDefinitions.CA_DATA_CALENDAR));
            }
            else
            {
                PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
                Marshal.FreeHGlobal(m_pCalendarBuffer);
            }
            Marshal.FreeHGlobal(buffer);
            int iResult = DAContentAccess.CAEndOperation(hOperHandle);
            if (iResult != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CAEndOperation", iResult);
            }
            return iRet;
        }

        //===================================================================
        // ReadBookmarkItem
        //
        // Reads Bookmark item from device
        //
        //===================================================================
        private int ReadBookmarkItem(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID, ref CAContentAccess.CADataDefinitions.CA_DATA_BOOKMARK dataBookmark)
        {
            int hOperHandle=0;
            int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0, ref hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
            }
            dataBookmark.iSize = Marshal.SizeOf(dataBookmark);
            dataBookmark.pstrBookMarkUrl = "";
            dataBookmark.pstrTitle = "";
            dataBookmark.pstrUrlShortcut = "";
            // Allocate memory for buffers
            IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
            Marshal.StructureToPtr(UID, buffer, true);
            m_pBookmarkBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(dataBookmark));
            Marshal.StructureToPtr(dataBookmark, m_pBookmarkBuffer, true);
            iRet = DAContentAccess.CAReadItem(hOperHandle, buffer, DAContentAccessDefinitions.CA_OPTION_USE_CACHE, CADataDefinitions.CA_DATA_FORMAT_STRUCT, m_pBookmarkBuffer);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Copy data from buffer
                dataBookmark = (CAContentAccess.CADataDefinitions.CA_DATA_BOOKMARK)Marshal.PtrToStructure(m_pBookmarkBuffer, typeof(CAContentAccess.CADataDefinitions.CA_DATA_BOOKMARK));
            }
            else
            {
                PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
                Marshal.FreeHGlobal(m_pBookmarkBuffer);
            }
            Marshal.FreeHGlobal(buffer);
            int iResult = DAContentAccess.CAEndOperation(hOperHandle);
            if (iResult != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CAEndOperation", iResult);
            }
            return iRet;
        }

        //===================================================================
        // CalendarItemType2String
        // 
        // Converts calendar item type values to string
        // 
        //===================================================================
        private string CalendarItemType2String(int iInfoField)
        {
            if (iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_MEETING)
            {
                return "Meeting";
            }
            else if (iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_CALL)
            {
                return "Call";
            }
            else if (iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_BIRTHDAY)
            {
                return "Birthday";
            }
            else if (iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_MEMO)
            {
                return "Memo";
            }
            else if (iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_REMINDER)
            {
                return "Reminder";
            }
            else if (iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_NOTE)
            {
                return "Note";
            }
            else if (iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_TODO)
            {
                return "Todo";
            }
            return "Unknown";
        }

        //===================================================================
        // FreeCalendarData
        //
        // Frees allocated memory of Calendar
        //
        //===================================================================
        private void FreeCalendarData()
        {
            // Free memory allocated by DA API
            int iRet = DAContentAccess.CAFreeItemData(m_hCalendar, CADataDefinitions.CA_DATA_FORMAT_STRUCT, m_pCalendarBuffer);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iRet);
            Marshal.FreeHGlobal(m_pCalendarBuffer);
            m_pCalendarBuffer = IntPtr.Zero;
        }

        //===================================================================
        // FreeBookmarkData
        //
        // Frees allocated memory of Bookmark
        //
        //===================================================================
        private void FreeBookmarkData()
        {
            // Free memory allocated by DA API
            int iRet = DAContentAccess.CAFreeItemData(m_hBookmark, CADataDefinitions.CA_DATA_FORMAT_STRUCT, m_pBookmarkBuffer);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iRet);
            Marshal.FreeHGlobal(m_pBookmarkBuffer);
            m_pBookmarkBuffer = IntPtr.Zero;
        }

        //===================================================================
        // GetCalendarDetails
        //
        // Read selected calendar item from phone and show details in list view.
        //
        //===================================================================
        private void GetCalendarDetails(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID pUID)
        {
            int hOperHandle = 0;
            int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0,ref  hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
            }
            CAContentAccess.CADataDefinitions.CA_DATA_CALENDAR dataCalendar = new CADataDefinitions.CA_DATA_CALENDAR();
            iRet = ReadCalendarItem(pUID, ref dataCalendar);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Calendar item type
                System.Windows.Forms.ListViewItem itemX = new System.Windows.Forms.ListViewItem();
                itemX.Text = "Item type";
                LVW_ItemList.Items.Add(itemX);
                itemX.SubItems.Add(CalendarItemType2String(dataCalendar.iInfoField));
                // Get note start date and format it
                System.DateTime startDate = new DateTime();
                System.DateTime dateEmpty = new DateTime();
                startDate = ConvertPIMDataDate(dataCalendar.noteStartDate);
                if (!startDate.Equals(dateEmpty))
                {
                    System.Windows.Forms.ListViewItem item1 = new System.Windows.Forms.ListViewItem();
                    item1.Text = "Start date";
                    LVW_ItemList.Items.Add(item1);
                    item1.SubItems.Add(startDate.ToString());
                }
                // Get note end date and format it
                System.DateTime endDate;
                endDate = ConvertPIMDataDate(dataCalendar.noteEndDate);
                if (!endDate.Equals(dateEmpty))
                {
                    System.Windows.Forms.ListViewItem item2 = new System.Windows.Forms.ListViewItem();
                    item2.Text = "End date";
                    LVW_ItemList.Items.Add(item2);
                    item2.SubItems.Add(endDate.ToString());
                }
                // Get note alarm time and format it
                System.DateTime alarmDate;
                alarmDate = ConvertPIMDataDate(dataCalendar.noteAlarmTime);
                if (!alarmDate.Equals(dateEmpty))
                {
                    System.Windows.Forms.ListViewItem item3 = new System.Windows.Forms.ListViewItem();
                    item3.Text = "Alarm date";
                    LVW_ItemList.Items.Add(item3);
                    item3.SubItems.Add(alarmDate.ToString());
                }
                // Show recurrence
                System.Windows.Forms.ListViewItem item4 = new System.Windows.Forms.ListViewItem();
                item4.Text = "Recurrence";
                LVW_ItemList.Items.Add(item4);
                item4.SubItems.Add(PIMCalendarRecurrence2String(dataCalendar.iRecurrence));
                // Get recurrence end date and format it
                System.DateTime recurrenceDate;
                recurrenceDate = ConvertPIMDataDate(dataCalendar.recurrenceEndDate);
                if (!recurrenceDate.Equals(dateEmpty))
                {
                    System.Windows.Forms.ListViewItem item5 = new System.Windows.Forms.ListViewItem();
                    item5.Text = "Recurrence end date";
                    LVW_ItemList.Items.Add(item5);
                    item5.SubItems.Add(recurrenceDate.ToString());
                }
                // Get SubItems
                if (dataCalendar.bItemCount > 0)
                {
                    Int64 pDataItems = 0;
                    int counter = 0;
                    for (counter = 0; counter < dataCalendar.bItemCount; counter ++)
                    {
                        CAContentAccess.CADataDefinitions.CA_DATA_ITEM dataItem;
                        pDataItems = dataCalendar.pDataItems.ToInt64() + (counter * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM)));
                        dataItem = (CAContentAccess.CADataDefinitions.CA_DATA_ITEM)Marshal.PtrToStructure(new IntPtr(pDataItems), typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                        if (dataItem.iFieldType == CADataDefinitions.CA_FIELD_TYPE_CALENDAR)
                        {
                            if (dataItem.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_DESCRIPTION)
                            {
                                string tmpString = Marshal.PtrToStringUni(dataItem.pCustomData);
                                System.Windows.Forms.ListViewItem item6 = new System.Windows.Forms.ListViewItem();
                                item6.Text = "Description";
                                LVW_ItemList.Items.Add(item6);
                                item6.SubItems.Add(tmpString);
                            }
                            else if (dataItem.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_LOCATION)
                            {
                                string tmpString = Marshal.PtrToStringUni(dataItem.pCustomData);
                                System.Windows.Forms.ListViewItem item7 = new System.Windows.Forms.ListViewItem();
                                item7.Text = "Location";
                                LVW_ItemList.Items.Add(item7);
                                item7.SubItems.Add(tmpString);
                            }
                            else if (dataItem.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_ITEM_DATA)
                            {
                                if (dataCalendar.iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_MEETING)
                                {
                                    string tmpString = Marshal.PtrToStringUni(dataItem.pCustomData);
                                    System.Windows.Forms.ListViewItem item8 = new System.Windows.Forms.ListViewItem();
                                    item8.Text = "Detail";
                                    LVW_ItemList.Items.Add(item8);
                                    item8.SubItems.Add(tmpString);
                                }
                                else if (dataCalendar.iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_CALL)
                                {
                                    string tmpString = Marshal.PtrToStringUni(dataItem.pCustomData);
                                    System.Windows.Forms.ListViewItem item9 = new System.Windows.Forms.ListViewItem();
                                    item9.Text = "Number";
                                    LVW_ItemList.Items.Add(item9);
                                    item9.SubItems.Add(tmpString);
                                }
                                else if (dataCalendar.iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_BIRTHDAY)
                                {
                                    uint tmpDW = (uint)dataItem.pCustomData.ToInt32();
                                    System.Windows.Forms.ListViewItem item10 = new System.Windows.Forms.ListViewItem();
                                    item10.Text = "Year";
                                    LVW_ItemList.Items.Add(item10);
                                    item10.SubItems.Add(tmpDW.ToString());
                                }
                            }
                            else if (dataItem.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_TODO_PRIORITY)
                            {
                                int tmpDW = dataItem.pCustomData.ToInt32();
                                System.Windows.Forms.ListViewItem item11 = new System.Windows.Forms.ListViewItem();
                                item11.Text = "Priority";
                                LVW_ItemList.Items.Add(item11);
                                item11.SubItems.Add(PIMCalendarTodoPriority2String(tmpDW));
                            }
                            else if (dataItem.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_TODO_STATUS)
                            {
                                int tmpDW = dataItem.pCustomData.ToInt32();
                                System.Windows.Forms.ListViewItem item12 = new System.Windows.Forms.ListViewItem();
                                item12.Text = "Status";
                                LVW_ItemList.Items.Add(item12);
                                item12.SubItems.Add(PIMCalendarTodoStatus2String(tmpDW));
                            }
                        }
                    }
                }

                // Free memory allocated by DA API
                FreeCalendarData();
            }
            else
            {
                PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
            }
            iRet = DAContentAccess.CAEndOperation(hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
            }
        }

        //===================================================================
        // GetBookmarkDetails
        //
        // Read selected Bookmark item from phone and show details in list view.
        //
        //===================================================================
        private void GetBookmarkDetails(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID pUID)
        {
            int hOperHandle = 0;
            int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0, ref hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
            }
            CAContentAccess.CADataDefinitions.CA_DATA_BOOKMARK dataBookmark = new CAContentAccess.CADataDefinitions.CA_DATA_BOOKMARK();
            iRet = ReadBookmarkItem(pUID, ref dataBookmark);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Bookmark data
                System.Windows.Forms.ListViewItem itemA = new System.Windows.Forms.ListViewItem();
                itemA.Text = "Title";
                LVW_ItemList.Items.Add(itemA);
                itemA.SubItems.Add(dataBookmark.pstrTitle);
                System.Windows.Forms.ListViewItem itemB = new System.Windows.Forms.ListViewItem();
                itemB.Text = "URL";
                LVW_ItemList.Items.Add(itemB);
                itemB.SubItems.Add(dataBookmark.pstrBookMarkUrl);
                System.Windows.Forms.ListViewItem itemC = new System.Windows.Forms.ListViewItem();
                itemC.Text = "URL Shortcut";
                LVW_ItemList.Items.Add(itemC);
                itemC.SubItems.Add(dataBookmark.pstrUrlShortcut);
                // Free memory allocated by DA API
                FreeBookmarkData();
            }
            else
            {
                PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
            }
            iRet = DAContentAccess.CAEndOperation(hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
            }
        }


        //===================================================================
        // ReadSMS
        //
        // Reads SMS message from device
        //
        //===================================================================
        private int ReadSMS(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID, ref CAContentAccess.CADataDefinitions.CA_DATA_MSG dataSMS)
        {
            int hOperHandle=0;
            int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0,ref hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
            }
            dataSMS.iSize = Marshal.SizeOf(dataSMS);
            dataSMS.bAddressCount = 0;
            dataSMS.iDataLength = 0;
            dataSMS.iInfoField = 0;
            dataSMS.pAddress = IntPtr.Zero;
            dataSMS.pbData = IntPtr.Zero;
            GetEmptyPIMDate(ref dataSMS.messageDate);
            // Allocate memory for buffer
            IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
            Marshal.StructureToPtr(UID, buffer, true);
            m_pSMSBuffer = Marshal.AllocHGlobal(dataSMS.iSize);
            Marshal.StructureToPtr(dataSMS, m_pSMSBuffer, true);
            iRet = DAContentAccess.CAReadItem(hOperHandle, buffer, DAContentAccessDefinitions.CA_OPTION_USE_CACHE, CADataDefinitions.CA_DATA_FORMAT_STRUCT, m_pSMSBuffer);
            // iRet = CAReadItem(hOperHandle, buffer, 0, CA_DATA_FORMAT_STRUCT, m_pSMSBuffer)
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Copy data from buffer
                dataSMS = (CAContentAccess.CADataDefinitions.CA_DATA_MSG)Marshal.PtrToStructure(m_pSMSBuffer, typeof(CAContentAccess.CADataDefinitions.CA_DATA_MSG));
            }
            else
            {
                PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
                Marshal.FreeHGlobal(m_pSMSBuffer);
            }
            Marshal.FreeHGlobal(buffer);
            int iResult = DAContentAccess.CAEndOperation(hOperHandle);
            if (iResult != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CAEndOperation", iResult);
            }
            return iRet;
        }

        //===================================================================
        // FreeSMSData
        //
        // Frees allocated memory of SMS
        //
        //===================================================================
        private void FreeSMSData()
        {
            // Free memory allocated by DA API
            int iRet = DAContentAccess.CAFreeItemData(m_hSMS, CADataDefinitions.CA_DATA_FORMAT_STRUCT, m_pSMSBuffer);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iRet);
            Marshal.FreeHGlobal(m_pSMSBuffer);
            m_pSMSBuffer = IntPtr.Zero;
        }

        //===================================================================
        // GetSMSDetails
        //
        // Read selected SMS from phone and show details in list view.
        //
        //===================================================================
        private void GetSMSDetails(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID)
        {
            // Read SMS item data from device
            CAContentAccess.CADataDefinitions.CA_DATA_MSG dataMsg = new CADataDefinitions.CA_DATA_MSG();
            int iRet = ReadSMS(UID, ref dataMsg);
            if (iRet == PCCSErrors.CONA_OK)
            {
                int i;
                // Addresses
                for (i = 0; i < dataMsg.bAddressCount; i++)
                {
                    // Calculate beginning of CA_DATA_ITEM structure of item 'i'
                    Int64 iPtr = dataMsg.pAddress.ToInt64() + i * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                    // Convert integer to pointer
                    IntPtr ptr = new IntPtr(iPtr);
                    CAContentAccess.CADataDefinitions.CA_DATA_ADDRESS itemData;
                    itemData = (CAContentAccess.CADataDefinitions.CA_DATA_ADDRESS)Marshal.PtrToStructure(ptr, typeof(CAContentAccess.CADataDefinitions.CA_DATA_ADDRESS));
                    // Add item to list view
                    System.Windows.Forms.ListViewItem itemX = new System.Windows.Forms.ListViewItem();
                    itemX.Text = "Address";
                    LVW_ItemList.Items.Add(itemX);
                    itemX.SubItems.Add(itemData.pstrAddress);
                }
                if (dataMsg.iDataLength > 0)
                {
                    if ((CADataDefinitions.CA_GET_DATA_FORMAT(dataMsg.iInfoField)) == CADataDefinitions.CA_DATA_FORMAT_UNICODE)
                    {
                        if (!IntPtr.Zero.Equals(dataMsg.pbData))
                        {
                            // Add item to list view
                            System.Windows.Forms.ListViewItem itemX = new System.Windows.Forms.ListViewItem();
                            itemX.Text = "Message";
                            LVW_ItemList.Items.Add(itemX);
                            string strData = Marshal.PtrToStringUni(dataMsg.pbData, dataMsg.iDataLength / 2);
                            itemX.SubItems.Add(strData);
                        }
                        else
                        {
                            // No data, GMS or other kind of message?
                        }
                    }
                    else
                    {
                        // Message in data format
                    }
                }
                // Get message date and format it
                System.DateTime dateMsg = new DateTime();
                System.DateTime dateEmpty = new DateTime();
                dateMsg = ConvertPIMDataDate(dataMsg.messageDate);
                if (!dateMsg.Equals(dateEmpty))
                {
                    // Add item to list view
                    System.Windows.Forms.ListViewItem itemX = new System.Windows.Forms.ListViewItem();
                    itemX.Text = "Date";
                    LVW_ItemList.Items.Add(itemX);
                    itemX.SubItems.Add(dateMsg.ToString());
                }
                // Message status
                System.Windows.Forms.ListViewItem itemY = new System.Windows.Forms.ListViewItem();
                itemY.Text = "Status";
                LVW_ItemList.Items.Add(itemY);
                itemY.SubItems.Add(PIMMessageStatus2String(dataMsg.iInfoField));
                FreeSMSData();
            }
        }

        //===================================================================
        // ReadMMS
        //
        // Reads MMS message from device
        //
        //===================================================================
        private int ReadMMS(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID, ref CAContentAccess.CADataDefinitions.CA_MMS_DATA dataMMS)
        {
            int hOperHandle=0;
            int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0, ref hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
            }
            dataMMS.iSize = Marshal.SizeOf(dataMMS);
            dataMMS.iInfoField = 0;
            dataMMS.bAddressCount = 0;
            dataMMS.pAddress = IntPtr.Zero;
            dataMMS.iDataLength = 0;
            dataMMS.pbData = IntPtr.Zero;
            // Allocate memory for buffer
            IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
            Marshal.StructureToPtr(UID, buffer, true);
            m_pMMSBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_MMS_DATA)));
            Marshal.StructureToPtr(dataMMS, m_pMMSBuffer, true);
            iRet = DAContentAccess.CAReadItem(hOperHandle, buffer, DAContentAccessDefinitions.CA_OPTION_USE_CACHE, CADataDefinitions.CA_DATA_FORMAT_STRUCT, m_pMMSBuffer);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Copy data from buffer
                dataMMS = (CAContentAccess.CADataDefinitions.CA_MMS_DATA)Marshal.PtrToStructure(m_pMMSBuffer, typeof(CAContentAccess.CADataDefinitions.CA_MMS_DATA));
            }
            else
            {
                PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
                Marshal.FreeHGlobal(m_pMMSBuffer);
            }
            Marshal.FreeHGlobal(buffer);
            int iResult = DAContentAccess.CAEndOperation(hOperHandle);
            if (iResult != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CAEndOperation", iResult);
            }
            return iRet;
        }

        //===================================================================
        // FreeMMSData
        //
        // Frees allocated memory of MMS
        //
        //===================================================================
        private void FreeMMSData()
        {
            // Free memory allocated by DA API
            int iRet = DAContentAccess.CAFreeItemData(m_hMMS, CADataDefinitions.CA_DATA_FORMAT_STRUCT, m_pMMSBuffer);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iRet);
            Marshal.FreeHGlobal(m_pMMSBuffer);
            m_pMMSBuffer = IntPtr.Zero;
        }

        //===================================================================
        // GetMMSDetails
        //
        // Read selected MMS from phone and show details in list view.
        //
        //===================================================================
        private void GetMMSDetails(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID)
        {
            // Read MMS item data from device
            CAContentAccess.CADataDefinitions.CA_MMS_DATA dataMsg = new CADataDefinitions.CA_MMS_DATA();
            int iRet = ReadMMS(UID, ref dataMsg);
            if (iRet == PCCSErrors.CONA_OK)
            {
                int i;
                // Addresses
                for (i = 0; i < dataMsg.bAddressCount; i++)
                {
                    // Calculate beginning of CA_DATA_ITEM structure of item 'i'
                    Int64 iPtr = dataMsg.pAddress.ToInt64() + i * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                    // Convert integer to pointer
                    IntPtr ptr = new IntPtr(iPtr);
                    CAContentAccess.CADataDefinitions.CA_DATA_ADDRESS itemData;
                    itemData = (CAContentAccess.CADataDefinitions.CA_DATA_ADDRESS)Marshal.PtrToStructure(ptr, typeof(CAContentAccess.CADataDefinitions.CA_DATA_ADDRESS));
                    // Add item to list view
                    System.Windows.Forms.ListViewItem itemX = new System.Windows.Forms.ListViewItem();
                    itemX.Text = "Address";
                    LVW_ItemList.Items.Add(itemX);
                    itemX.SubItems.Add(itemData.pstrAddress);
                }
                // Get message date and format it
                System.DateTime dateMsg = new DateTime();
                System.DateTime dateEmpty = new DateTime();
                dateMsg = ConvertPIMDataDate(dataMsg.messageDate);
                if (!dateMsg.Equals(dateEmpty))
                {
                    // Add item to list view
                    System.Windows.Forms.ListViewItem itemX = new System.Windows.Forms.ListViewItem();
                    itemX.Text = "Date";
                    LVW_ItemList.Items.Add(itemX);
                    itemX.SubItems.Add(dateMsg.ToString());
                }
                // Message status
                System.Windows.Forms.ListViewItem itemY = new System.Windows.Forms.ListViewItem();
                itemY.Text = "Status";
                LVW_ItemList.Items.Add(itemY);
                itemY.SubItems.Add(PIMMessageStatus2String(dataMsg.iInfoField));
                FreeMMSData();
            }
        }


        //===================================================================
        // RefreshTreeView
        //
        // Refresh phone list to combo
        //
        //===================================================================
        public void RefreshTreeView()
        {
            // Clear all previous data
            Timer1.Enabled = false;
            TVW_Navigator.Enabled = false;

            CloseContactsConnection();
            CloseCalendarConnection();
            CloseSMSConnection();
            CloseMMSConnection();
            CloseBookmarkConnection();
            ClearListView();
            TVW_Navigator.Nodes.Clear();
            TVW_Navigator.Enabled = false;
            Cursor = System.Windows.Forms.Cursors.WaitCursor;
            if (m_hDMHandle == 0)
            {
                return;
            }
            int iRet = CONADeviceManagement.CONARefreshDeviceList(m_hDMHandle, 0);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CONARefreshDeviceList", iRet);

            CONADefinitions.CONAPI_DEVICE[] pDevices;
            int iDeviceCount = 0;
            iRet = CONADeviceManagement.CONAGetDeviceCount(m_hDMHandle, ref iDeviceCount);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CONAGetDeviceCount", iRet);
            if (iRet == PCCSErrors.CONA_OK & iDeviceCount > 0)
            {
                pDevices = null;
                pDevices = new CONADefinitions.CONAPI_DEVICE[iDeviceCount];
                
                // Allocate memory for buffer
                IntPtr buffer = Marshal.AllocHGlobal(iDeviceCount * Marshal.SizeOf(typeof(CONADefinitions.CONAPI_DEVICE)));
                // Get list of currently connected devices
                iRet = CONADeviceManagement.CONAGetDevices(m_hDMHandle, ref iDeviceCount, buffer);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CONAGetDevices", iRet);
                }
                else
                {
                    // Add each device to the tree view
                    int iDeviceIndex;
                    for (iDeviceIndex = 0; iDeviceIndex < iDeviceCount; iDeviceIndex++)
                    {
                        // Calculate beginning of CONAPI_DEVICE structure of item 'i'
                        Int64 iPtr = buffer.ToInt64() + iDeviceIndex * Marshal.SizeOf(typeof(CONADefinitions.CONAPI_DEVICE));
                        // Convert integer to pointer
                        IntPtr ptr = new IntPtr(iPtr);
                        // Copy data from buffer
                        pDevices[iDeviceIndex] = (CONADefinitions.CONAPI_DEVICE)Marshal.PtrToStructure(ptr, typeof(CONADefinitions.CONAPI_DEVICE));
                        // Insert phone item in tree view
                        System.Windows.Forms.TreeNode itemX = new System.Windows.Forms.TreeNode();
                        itemX.Text = pDevices[iDeviceIndex].pstrFriendlyName;
                        itemX.ImageIndex = m_iIconPhoneIndex;
                        itemX.SelectedImageIndex = m_iIconPhoneIndex;
                        itemX.Tag = pDevices[iDeviceIndex].pstrSerialNumber;
                        TVW_Navigator.Nodes.Add(itemX);
                        GetContactsFolder(itemX.Tag.ToString(), itemX);
                        GetSMSFolders(itemX.Tag.ToString(), itemX);
                        GetMMSFolders(itemX.Tag.ToString(), itemX);
                        GetCalendarFolder(itemX.Tag.ToString(), itemX);
                        GetBookmarkFolder(itemX.Tag.ToString(), itemX);
                    }
                    // Free memory allocated by CONAGetDevices
                    CONADeviceManagement.CONAFreeDeviceStructure(iDeviceCount, buffer);
                    if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CONAFreeDeviceStructure", iRet);
                }
                Marshal.FreeHGlobal(buffer);
            }
            if (iRet == PCCSErrors.CONA_OK & iDeviceCount == 0)
            {
                System.Windows.Forms.TreeNode itemX = new System.Windows.Forms.TreeNode();
                itemX.Text = "No phones connected";
                itemX.ImageIndex = m_iIconNoPhoneIndex;
                itemX.SelectedImageIndex = m_iIconNoPhoneIndex;
                TVW_Navigator.Nodes.Add(itemX);
            }
            else
            {
                TVW_Navigator.Enabled = true;
            }
            Cursor = System.Windows.Forms.Cursors.Default;
            Timer1.Enabled = true;
            TVW_Navigator.Enabled = true;
        }

        //===================================================================
        // GetCurrentDevice
        //
        // Get's serial number for currently selected TreeNode item
        //
        //===================================================================
        private string GetCurrentDevice()
        {
            string functionReturnValue = null;
            System.Windows.Forms.TreeNode item = this.TVW_Navigator.SelectedNode;
            functionReturnValue = "";
            while (item != null)
            {
                if (item.ImageIndex == m_iIconPhoneIndex)
                {
                    functionReturnValue = item.Tag.ToString();
                    break; // TODO: might not be correct. Was : Exit While
                }
                item = item.Parent;
            }
            return functionReturnValue;
        }
        
        //===================================================================
        // GetCurrentDevice
        //
        // Get's serial number for currently given TreeNode item
        //
        //===================================================================
        private string GetCurrentDevice(System.Windows.Forms.TreeNode gItem)
        {
            string functionReturnValue = null;
            System.Windows.Forms.TreeNode item = gItem;
            functionReturnValue = "";
            while (item != null)
            {
                if (item.ImageIndex == m_iIconPhoneIndex)
                {
                    functionReturnValue = item.Tag.ToString();
                    break; // TODO: might not be correct. Was : Exit While
                }
                item = item.Parent;
            }
            return functionReturnValue;
        }

        //===================================================================
        // ClearListView
        //
        // Clear previous details
        //
        //===================================================================
        private void ClearListView()
        {
            if(pictureBox1.Image != null)
            {
                System.Drawing.Size size1 = this.Size;
                System.Drawing.Size size2 = pictureBox1.Size;
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;
                size1.Width = size1.Width - size2.Width - 15;
                this.Size = size1;
                System.IO.File.Delete(m_strFile);
            }
            LVW_ItemList.Items.Clear();
        }

        //===================================================================
        // TVW_Navigator_AfterSelect
        //
        // User has selected item in tree view. If item is contact or SMS
        // message, show details in list view.
        //
        //===================================================================
        private void TVW_Navigator_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
        {
            // Clear previous details
            ClearListView();
            // Disable "New" and "Delete" buttons
            BTN_New.Enabled = false;
            BTN_Delete.Enabled = false;
            BTN_Save.Enabled = false;
            BTN_NewFolder.Enabled = false;

            Cursor = System.Windows.Forms.Cursors.WaitCursor;

            System.Windows.Forms.TreeNode currentItem = new System.Windows.Forms.TreeNode();
            currentItem = e.Node;
            CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID = new DAContentAccessDefinitions.CA_ITEM_ID();
            string strSerialNumber = GetCurrentDevice();
            if (strSerialNumber.Length == 0)
            {
                return;
            }
            System.Windows.Forms.TreeNode parentItem = currentItem.Parent;
            int iImage = currentItem.ImageIndex;
            if (iImage == m_iIconPhoneIndex)
            {
                Cursor = System.Windows.Forms.Cursors.Default;
                return;
                // Phone item is selected
            }
            else if (iImage == m_iIconContactsIndex)
            {
                // Check PIM connection to contacts folder and open it if needed
                CheckContactsConnection(strSerialNumber);
                // Contacts folder selected
                m_hCurrentConnection = m_hContacts;
                BTN_New.Enabled = true;
            }
            else if (iImage == m_iIconCalendarIndex)
            {
                // Check PIM connection to Calendar folders and open it if needed
                CheckCalendarConnection(strSerialNumber);
                // Calendar folder selected
                m_hCurrentConnection = m_hCalendar;
                BTN_New.Enabled = true;
            }
            else if (iImage == m_iIconBookmarkIndex)
            {
                // Check PIM connection to Bookmark folders and open it if needed
                CheckBookmarkConnection(strSerialNumber);
                // Bookmark folder selected
                m_hCurrentConnection = m_hBookmark;
                BTN_New.Enabled = true;
                BTN_NewFolder.Enabled = true;
                BTN_Delete.Enabled = true;
            }
            else if (iImage == m_iIconSMSMessagesIndex)
            {
                // Check PIM connection to SMS folders and open it if needed
                CheckSMSConnection(strSerialNumber);
                // SMS folder selected
                m_hCurrentConnection = m_hSMS;
                if (currentItem.Parent.ImageIndex == m_iIconSMSMessagesIndex)
                {
                    BTN_NewFolder.Enabled = true;
                }              
                BTN_New.Enabled = true;
                BTN_Delete.Enabled = true;
            }
            else if (iImage == m_iIconMMSMessagesIndex)
            {
                // Check PIM connection to MMS folders and open it if needed
                CheckMMSConnection(strSerialNumber);
                // MMS folder selected
                m_hCurrentConnection = m_hMMS;
                BTN_New.Enabled = false;
            }
            else if (iImage == m_iIconContactIndex)
            {
                // Contact item is selected
                // Check PIM connection to contacts folder and open it if needed
                CheckContactsConnection(strSerialNumber);
                m_hCurrentConnection = m_hContacts;
                UID = MapCAItemIDToUID((CAItemID)TVW_Navigator.SelectedNode.Tag);
                GetContactDetails(UID);
                FreeUIDMappingMemory(UID);
                // Set handle to current folder item
                // PIM item is selected, delete button can be enabled
                BTN_Delete.Enabled = true;
                BTN_Save.Enabled = true;
            }
            else if (iImage == m_iIconCalendarItemIndex)
            {
                // Calendar item is selected
                CheckCalendarConnection(strSerialNumber);
                m_hCurrentConnection = m_hCalendar;
                UID = MapCAItemIDToUID((CAItemID)TVW_Navigator.SelectedNode.Tag);
                GetCalendarDetails(UID);
                FreeUIDMappingMemory(UID);
                // PIM item is selected, delete button can be enabled
                BTN_Delete.Enabled = true;
                BTN_Save.Enabled = true;
                BTN_New.Enabled = true;
            }
            else if (iImage == m_iIconBookmarkItemIndex)
            {
                // Calendar item is selected
                CheckBookmarkConnection(strSerialNumber);
                m_hCurrentConnection = m_hBookmark;
                UID = MapCAItemIDToUID((CAItemID)TVW_Navigator.SelectedNode.Tag);
                GetBookmarkDetails(UID);
                FreeUIDMappingMemory(UID);
                // PIM item is selected, delete button can be enabled
                BTN_Delete.Enabled = true;
                BTN_Save.Enabled = true;
                BTN_New.Enabled = true;
            }
            else if (iImage == m_iIconSMSIndex)
            {
                // SMS item is selected
                CheckSMSConnection(strSerialNumber);
                m_hCurrentConnection = m_hSMS;
                UID = MapCAItemIDToUID((CAItemID)TVW_Navigator.SelectedNode.Tag);
                GetSMSDetails(UID);
                FreeUIDMappingMemory(UID);
                // PIM item is selected, delete button can be enabled
                BTN_Delete.Enabled = true;
                BTN_Save.Enabled = true;
            }
            else if (iImage == m_iIconMMSIndex)
            {
                // MMS item is selected
                CheckMMSConnection(strSerialNumber);
                m_hCurrentConnection = m_hMMS;
                UID = MapCAItemIDToUID((CAItemID)TVW_Navigator.SelectedNode.Tag);
                GetMMSDetails(UID);
                FreeUIDMappingMemory(UID);
                // PIM item is selected, delete button can be enabled
                BTN_Delete.Enabled = true;
                BTN_Save.Enabled = true;
            }
            Cursor = System.Windows.Forms.Cursors.Default;
        }

        //===================================================================
        // GetContactNumberBuffer
        //
        // Fills contact name in CA_DATA_ITEM struct and copies it to
        // unmanaged memory buffer
        //
        //===================================================================
        private IntPtr GetContactPIMBuffer(
            int iCount,
            string strFirstName,
            string strLastName,
            string strJob,
            string strCompany,
            DateTime dtBirthDay )
        {
            CAContentAccess.CADataDefinitions.CA_DATA_ITEM[] dataItem = new CADataDefinitions.CA_DATA_ITEM[iCount];
            int iIndex=0;

            if (strFirstName.Length > 0) {
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_PI;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_FN;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strFirstName);
                iIndex++;
            }
            if (strLastName.Length > 0) {
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_PI;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_LN;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strLastName);
                iIndex++;
            }
            if (strJob.Length > 0) {
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_PI;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_JOB_TITLE;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strJob);
                iIndex++;
            }
            if (strCompany.Length > 0) {
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_PI;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_JOB_TITLE;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strCompany);
                iIndex++;
            }
            if (iIndex < iCount) {
                CADataDefinitions.CA_DATA_DATE dataDate = new CADataDefinitions.CA_DATA_DATE(); 
                IntPtr datePtr = IntPtr.Zero;
                GetEmptyPIMDate(ref dataDate);
                dataDate.wYear = (ushort)dtBirthDay.Year;
                dataDate.bMonth = (byte)dtBirthDay.Month;
                dataDate.bDay = (byte)dtBirthDay.Day;
                dataDate.iSize = Marshal.SizeOf(dataDate);
                datePtr = Marshal.AllocHGlobal(dataDate.iSize);
                Marshal.StructureToPtr(dataDate, datePtr, true);
                // 
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_PI;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_BIRTHDAY;
                dataItem[iIndex].pCustomData = datePtr;
                iIndex++;
            }       
            // Allocate memory for buffer
            int iSize = iCount * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
            IntPtr bufDataItem = Marshal.AllocHGlobal(iSize);
            for (iIndex = 0; iIndex < iCount; iIndex++)
            {
                // Calculate beginning of CA_DATA_ITEM structure of item 'iIndex'
                Int64 iPtr = bufDataItem.ToInt64() + iIndex * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                // Convert integer to pointer
                IntPtr ptr = new IntPtr(iPtr);
                Marshal.StructureToPtr(dataItem[iIndex], ptr, true);
            }
            return bufDataItem;
        }

        //===================================================================
        // GetContactNumberBuffer
        //
        // Fills phone numbers in CA_DATA_ITEM struct and copies it to
        // unmanaged memory buffer
        //
        //===================================================================
        private IntPtr GetContactNumberBuffer(int iCount, string strGeneral, string strMobile, string strHome, string strWork, string strFax)
        {
            CAContentAccess.CADataDefinitions.CA_DATA_ITEM[] dataItem = new CADataDefinitions.CA_DATA_ITEM[iCount];
            
            int iIndex=0;
            if (strGeneral.Length > 0)
            {
                // Mobile number
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_NUMBER;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_TEL;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strGeneral);
                iIndex += 1;
            }
            if (strMobile.Length > 0)
            {
                // Mobile number
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_NUMBER;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_MOBILE;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strMobile);
                iIndex += 1;
            }
            if (strHome.Length > 0)
            {
                // Home number
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_NUMBER;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_TEL_HOME;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strHome);
                iIndex += 1;
            }
            if ((strWork.Length > 0))
            {
                // Work number
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_NUMBER;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_TEL_WORK;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strWork);
                iIndex += 1;
            }
            if ((strFax.Length > 0))
            {
                // Work number
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_NUMBER;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_FAX;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strFax);
                iIndex += 1;
            }
            // Allocate memory for buffer
            int iSize = iCount * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
            IntPtr bufDataItem = Marshal.AllocHGlobal(iSize);
            for (iIndex = 0; iIndex < iCount; iIndex++)
            {
                // Calculate beginning of CA_DATA_ITEM structure of item 'iIndex'
                Int64 iPtr = bufDataItem.ToInt64() + iIndex * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                // Convert integer to pointer
                IntPtr ptr = new IntPtr(iPtr);
                Marshal.StructureToPtr(dataItem[iIndex], ptr, true);
            }
            return bufDataItem;
        }

        //===================================================================
        // GetContactAddressBuffer
        //
        // Fills addresses in CA_DATA_ITEM struct and copies it to
        // unmanaged memory buffer
        //
        //===================================================================
        private IntPtr GetContactAddressBuffer(
            int iCount, 
            string strEmail, 
            string strWeb, 
            bool bHasAddress, 
            string strPOBox,
            string strPCode,
            string strStreet,
            string strCity,
            string strState, 
            string strCountry, 
            string strEData ) 
        {
            CAContentAccess.CADataDefinitions.CA_DATA_ITEM[] dataItem = new CADataDefinitions.CA_DATA_ITEM[iCount];
            int iIndex=0;
            
            if (strEmail.Length > 0 ) {
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_ADDRESS;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_EMAIL;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strEmail);
                iIndex++;
            }
            if (strWeb.Length > 0 ) {
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_ADDRESS;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_WEB;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strWeb);
                iIndex++;
            }
            if ( bHasAddress) {
                CADataDefinitions.CA_DATA_POSTAL_ADDRESS dataAddress = new CADataDefinitions.CA_DATA_POSTAL_ADDRESS();
                dataAddress.iSize = Marshal.SizeOf(dataAddress);
                dataAddress.pstrPOBox = strPOBox;
                dataAddress.pstrPostalCode = strPCode;
                dataAddress.pstrStreet = strStreet;
                dataAddress.pstrCity = strCity;
                dataAddress.pstrState = strState;
                dataAddress.pstrCountry = strCountry;
                dataAddress.pstrExtendedData = strEData;
            
                IntPtr aDataPtr = Marshal.AllocHGlobal(dataAddress.iSize);
                Marshal.StructureToPtr(dataAddress, aDataPtr, true);
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_ADDRESS;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_POSTAL;
                dataItem[iIndex].pCustomData = aDataPtr;
                iIndex += 1;
            }

            // Allocate memory for buffer
            int iSize = iCount * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
            IntPtr bufDataItem = Marshal.AllocHGlobal(iSize);
            for (iIndex = 0; iIndex < iCount; iIndex++)
            {
                // Calculate beginning of CA_DATA_ITEM structure of item 'iIndex'
                Int64 iPtr = bufDataItem.ToInt64() + iIndex * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                // Convert integer to pointer
                IntPtr ptr = new IntPtr(iPtr);
                Marshal.StructureToPtr(dataItem[iIndex], ptr, true);
            }
            return bufDataItem;
        }

        //===================================================================
        // GetContactGeneralBuffer
        //
        // Fills general info in CA_DATA_ITEM struct and copies it to
        // unmanaged memory buffer
        //
        //===================================================================
        private IntPtr GetContactGeneralBuffer( int iCount, string strNote ) 
        {
            CAContentAccess.CADataDefinitions.CA_DATA_ITEM[] dataItem = new CADataDefinitions.CA_DATA_ITEM[iCount];
            int iIndex=0;
            
            if ( strNote.Length > 0 ) {
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CONTACT_GENERAL;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_NOTE;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strNote);
                iIndex++;
            }
            // Allocate memory for buffer
            int iSize = iCount * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
            IntPtr bufDataItem = Marshal.AllocHGlobal(iSize);
            for (iIndex = 0; iIndex < iCount; iIndex++)
            {
                // Calculate beginning of CA_DATA_ITEM structure of item 'iIndex'
                Int64 iPtr = bufDataItem.ToInt64() + iIndex * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                // Convert integer to pointer
                IntPtr ptr = new IntPtr(iPtr);
                Marshal.StructureToPtr(dataItem[iIndex], ptr, true);
            }
            return bufDataItem;
        }

        //===================================================================
        // FreeContactWriteBuffers
        //
        // Frees global memory allocated for Conatc write operation
        //
        //===================================================================
        private void FreeContactWriteBuffers(ref CADataDefinitions.CA_DATA_CONTACT dataContact)
        {
            int iCount = dataContact.bPICount;
            IntPtr iPtr = dataContact.pPIFields;
            if (iPtr != IntPtr.Zero)
            {
                CADataDefinitions.CA_DATA_ITEM dataItem = new CADataDefinitions.CA_DATA_ITEM();
                for (int i = 0; i < iCount; i++)
                {
                    dataItem = (CADataDefinitions.CA_DATA_ITEM)Marshal.PtrToStructure(iPtr, typeof(CADataDefinitions.CA_DATA_ITEM));
                    if (dataItem.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_BIRTHDAY)
                        Marshal.FreeHGlobal(dataItem.pCustomData);
                    else
                        Marshal.FreeCoTaskMem(dataItem.pCustomData);
                    iPtr = (IntPtr)(iPtr.ToInt64() + Marshal.SizeOf(dataItem));
                }
                Marshal.FreeHGlobal(dataContact.pPIFields);
            }
            iCount = dataContact.bNumberCount;
            iPtr = dataContact.pNumberFields;
            if (iPtr != IntPtr.Zero)
            {
                CADataDefinitions.CA_DATA_ITEM dataItem = new CADataDefinitions.CA_DATA_ITEM();
                for (int i = 0; i < iCount; i++)
                {
                    dataItem = (CADataDefinitions.CA_DATA_ITEM)Marshal.PtrToStructure(iPtr, typeof(CADataDefinitions.CA_DATA_ITEM));
                    Marshal.FreeCoTaskMem(dataItem.pCustomData);
                    iPtr = (IntPtr)(iPtr.ToInt64() + Marshal.SizeOf(dataItem));
                }
                Marshal.FreeHGlobal(dataContact.pNumberFields);
            }
            iCount = dataContact.bAddressCount;
            iPtr = dataContact.pAddressFields;
            if (iPtr != IntPtr.Zero)
            {
                CADataDefinitions.CA_DATA_ITEM dataItem = new CADataDefinitions.CA_DATA_ITEM();
                for (int i = 0; i < iCount; i++)
                {
                    dataItem = (CADataDefinitions.CA_DATA_ITEM)Marshal.PtrToStructure(iPtr, typeof(CADataDefinitions.CA_DATA_ITEM));
                    if (dataItem.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_POSTAL)
                        Marshal.FreeHGlobal(dataItem.pCustomData);
                    else
                        Marshal.FreeCoTaskMem(dataItem.pCustomData);
                    iPtr = (IntPtr)(iPtr.ToInt64() + Marshal.SizeOf(dataItem));
                }
                Marshal.FreeHGlobal(dataContact.pAddressFields);
            }
            iCount = dataContact.bGeneralCount;
            iPtr = dataContact.pGeneralFields;
            if (iPtr != IntPtr.Zero)
            {
                CADataDefinitions.CA_DATA_ITEM dataItem = new CADataDefinitions.CA_DATA_ITEM();
                for (int i = 0; i < iCount; i++)
                {
                    dataItem = (CADataDefinitions.CA_DATA_ITEM)Marshal.PtrToStructure(iPtr, typeof(CADataDefinitions.CA_DATA_ITEM));
                    Marshal.FreeCoTaskMem(dataItem.pCustomData);
                    iPtr = (IntPtr)(iPtr.ToInt64() + Marshal.SizeOf(dataItem));
                }
                Marshal.FreeHGlobal(dataContact.pGeneralFields);
            }
        }

        //===================================================================
        // ShowNewContactDlg
        //
        // Shows "New Contact" dialog and writes contact to device
        //
        //===================================================================
        private void ShowNewContactDlg()
        {
            // Open "New Contact" dialog
            ContactDlg dlg = new ContactDlg();
            
            // Set birthday value to next week, if changed save value
            DateTime dtInitialDate = DateTime.Now.AddDays(7);
            dlg.DTP_Birthday.Value = dtInitialDate;

            // TODO: Modifications missing after this...

            if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return; 
            }
            //
            CheckContactsConnection(GetCurrentDevice());
            // User has filled contact information in dialog and clicked OK
            CAContentAccess.CADataDefinitions.CA_DATA_CONTACT dataContact = new CADataDefinitions.CA_DATA_CONTACT();
            dataContact.iSize = Marshal.SizeOf(dataContact);
            // Contact name
            dataContact.bPICount = 0;
            if (dlg.TXT_FirstName.Text.Length > 0) dataContact.bPICount++;
            if (dlg.TXT_LastName.Text.Length > 0) dataContact.bPICount++;
            if (dlg.TXT_Job.Text.Length > 0) dataContact.bPICount++;
            if (dlg.TXT_Company.Text.Length > 0) dataContact.bPICount++;
            if (dlg.DTP_Birthday.Value != dtInitialDate) dataContact.bPICount++;

            if (dataContact.bPICount > 0 ) {
                dataContact.pPIFields = GetContactPIMBuffer(dataContact.bPICount, dlg.TXT_FirstName.Text, dlg.TXT_LastName.Text, dlg.TXT_Job.Text, dlg.TXT_Company.Text, dlg.DTP_Birthday.Value);
            }

            // Phone numbers
            int iCount=0;
            if (dlg.TXT_General.Text.Length > 0) iCount++;
            if (dlg.TXT_Mobile.Text.Length > 0) iCount++;
            if (dlg.TXT_Home.Text.Length > 0) iCount++;
            if (dlg.TXT_Work.Text.Length > 0) iCount++;
            if (dlg.TXT_Fax.Text.Length > 0) iCount++;
            if (iCount > 0)
            {
                dataContact.bNumberCount = (byte)iCount;
                dataContact.pNumberFields = GetContactNumberBuffer(iCount, dlg.TXT_General.Text, dlg.TXT_Mobile.Text, dlg.TXT_Home.Text, dlg.TXT_Work.Text, dlg.TXT_Fax.Text );
            }

            // Addresses
            bool bHasAddress = false;
            int iACount = 0;
            if (( dlg.strPOBox.Length > 0) | (dlg.strPostalCode.Length > 0) | (dlg.strStreet.Length > 0) |
                (dlg.strCity.Length > 0) | (dlg.strState.Length > 0) | (dlg.strCountry.Length > 0 ) |
                (dlg.strExtentedData.Length > 0)) {
                bHasAddress = true;
                iACount ++;
            }
            if (dlg.TXT_Email.Text.Length > 0) iACount ++;
            if (dlg.TXT_Web.Text.Length > 0 ) iACount ++;
       
            if (iACount > 0) {
                dataContact.bAddressCount = (byte)iACount;
                dataContact.pAddressFields = GetContactAddressBuffer(iACount, dlg.TXT_Email.Text, dlg.TXT_Web.Text, bHasAddress, dlg.strPOBox, dlg.strPostalCode, dlg.strStreet, dlg.strCity, dlg.strState, dlg.strCountry, dlg.strExtentedData);
            }

            // Just one item, but let's make room for future extensions
            int iGCount = 0;
            if (dlg.TXT_Note.Text.Length > 0) iGCount ++;
            if (iGCount > 0) {
                dataContact.bGeneralCount = (byte)iGCount;
                dataContact.pGeneralFields = GetContactGeneralBuffer(iGCount, dlg.TXT_Note.Text);
            }
            System.Windows.Forms.TreeNode contactsNode;
            if (TVW_Navigator.SelectedNode.ImageIndex == m_iIconContactsIndex)
                contactsNode = TVW_Navigator.SelectedNode;
            else
                contactsNode = TVW_Navigator.SelectedNode.Parent;
            CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;
                folderInfo = MapCAFolderInfoToCFI((CAFolderInfo)contactsNode.Tag);
            // Write new contact item to currently connected device
            int hOperHandle = 0;
            int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0, ref hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
            }
            // Register CA operation notification callback function
            CAContentAccess.DAContentAccess.CARegisterOperationCallback(hOperHandle, CONADefinitions.API_REGISTER, pCAOperationCallback);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterOperationCallback", iRet);
            CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID itemUid = new DAContentAccessDefinitions.CA_ITEM_ID();
            itemUid.iSize = Marshal.SizeOf(itemUid);
            itemUid.iFolderId = folderInfo.iFolderId;
            itemUid.iStatus = 0;
            itemUid.iTemporaryID = 0;
            itemUid.iUidLen = 0;
            itemUid.pbUid = IntPtr.Zero;
            IntPtr buf = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID)));
            Marshal.StructureToPtr(itemUid, buf, true);
            // Allocate memory for buffer
            IntPtr buf2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_CONTACT)));
            Marshal.StructureToPtr(dataContact, buf2, true);
            iRet = DAContentAccess.CAWriteItem(hOperHandle, buf, 0, CADataDefinitions.CA_DATA_FORMAT_STRUCT, buf2);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAWriteItem", iRet);
            try
            {
                FreeContactWriteBuffers(ref dataContact);
                Marshal.FreeHGlobal(buf2);
                Marshal.FreeHGlobal(buf);
            }
            catch
            {
            }
            iRet = DAContentAccess.CACommitOperations(hOperHandle, IntPtr.Zero);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CACommitOperations", iRet);
            }
            CAContentAccess.DAContentAccess.CARegisterOperationCallback(hOperHandle, CONADefinitions.API_UNREGISTER, pCAOperationCallback);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterOperationCallback", iRet);
            iRet = DAContentAccess.CAEndOperation(hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
            }
            contactsNode.Nodes.Clear();
            GetContacts(GetCurrentDevice(), contactsNode);
        }

        //===================================================================
        // GetSMSAddressBuffer
        //
        // Fills SMS address in CA_DATA_ADDRESS struct and copies it to
        // unmanaged memory buffer
        //
        //===================================================================
        private System.IntPtr GetSMSAddressBuffer(string strNumber)
        {
            CAContentAccess.CADataDefinitions.CA_DATA_ADDRESS dataAddress;
            dataAddress = new CAContentAccess.CADataDefinitions.CA_DATA_ADDRESS();
            dataAddress.iSize = Marshal.SizeOf(dataAddress);
            dataAddress.iAddressInfo = CADataDefinitions.CA_MSG_ADDRESS_TYPE_NUMBER;
            dataAddress.pstrAddress = strNumber;
            // Allocate memory for buffer
            IntPtr bufDataAddress = Marshal.AllocHGlobal(Marshal.SizeOf(dataAddress));
            Marshal.StructureToPtr(dataAddress, bufDataAddress, false);
            return bufDataAddress;
        }


        //===================================================================
        // ShowNewSMSDlg
        //
        // Shows "New Text Message" dialog and writes SMS to device
        //
        //===================================================================
        private void ShowNewSMSDlg()
        {
            // Open "New Text Message" dialog
            SmsMessageDlg dlg = new SmsMessageDlg();
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                //
                CheckSMSConnection(GetCurrentDevice());
                 CAContentAccess.CADataDefinitions.CA_DATA_MSG dataMsg= new CADataDefinitions.CA_DATA_MSG();
                dataMsg.iSize = Marshal.SizeOf(dataMsg);
                CADataDefinitions.CA_SET_DATA_FORMAT(ref dataMsg.iInfoField, CADataDefinitions.CA_DATA_FORMAT_UNICODE);
                CADataDefinitions.CA_SET_DATA_CODING(ref dataMsg.iInfoField, CADataDefinitions.CA_DATA_CODING_UNICODE);
                CADataDefinitions.CA_SET_MESSAGE_STATUS(ref dataMsg.iInfoField, CADataDefinitions.CA_MESSAGE_STATUS_DRAFT);
                CADataDefinitions.CA_SET_MESSAGE_TYPE(ref dataMsg.iInfoField, CADataDefinitions.CA_SMS_SUBMIT);
                // Phone number
                if ((dlg.TXT_Number.Text.Length > 0))
                {
                    dataMsg.bAddressCount = 1;
                    dataMsg.pAddress = GetSMSAddressBuffer(dlg.TXT_Number.Text);
                }
                // Message body text
                int iLength = dlg.TXT_Message.Text.Length;
                if ((iLength > 0))
                {
                    dataMsg.iDataLength = iLength * 2;
                    dataMsg.pbData = Marshal.StringToCoTaskMemUni(dlg.TXT_Message.Text);
                }
                // Set message date
                GetCurrentPIMDate(ref dataMsg.messageDate);
                System.Windows.Forms.TreeNode smsNode;
                if (TVW_Navigator.SelectedNode.ImageIndex == m_iIconSMSMessagesIndex)
                    smsNode = TVW_Navigator.SelectedNode;
                else
                    smsNode = TVW_Navigator.SelectedNode.Parent;
                CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;
                folderInfo = MapCAFolderInfoToCFI((CAFolderInfo)smsNode.Tag);
                // Write new SMS item to currently connected device
                int hOperHandle = 0;
                int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0, ref hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
                }
                CAContentAccess.DAContentAccess.CARegisterOperationCallback(hOperHandle, CONADefinitions.API_REGISTER, pCAOperationCallback);
                if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterOperationCallback", iRet);
                CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID itemUid = new DAContentAccessDefinitions.CA_ITEM_ID();
                itemUid.iSize = Marshal.SizeOf(itemUid);
                itemUid.iFolderId = folderInfo.iFolderId;
                itemUid.iFolderId = folderInfo.iFolderId;
                itemUid.iStatus = 0;
                itemUid.iTemporaryID = 0;
                itemUid.iUidLen = 0;
                itemUid.pbUid = IntPtr.Zero;
                IntPtr buf = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID)));
                Marshal.StructureToPtr(itemUid, buf, true);
                // Allocate memory for buffer
                IntPtr buf2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_MSG)));
                Marshal.StructureToPtr(dataMsg, buf2, true);
                iRet = DAContentAccess.CAWriteItem(hOperHandle, buf, 0, CADataDefinitions.CA_DATA_FORMAT_STRUCT, buf2);
                if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAWriteItem", iRet);
                Marshal.FreeHGlobal(buf2);
                Marshal.FreeHGlobal(buf);

                //If iRet <> PCCSErrors.CONA_OK Then PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iRet)
                Marshal.FreeCoTaskMem(dataMsg.pbData);
                Marshal.FreeCoTaskMem(dataMsg.pAddress);

                iRet = DAContentAccess.CACommitOperations(hOperHandle, IntPtr.Zero);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CACommitOperations", iRet);
                }
                CAContentAccess.DAContentAccess.CARegisterOperationCallback(hOperHandle, CONADefinitions.API_UNREGISTER, pCAOperationCallback);
                if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterOperationCallback", iRet);
                iRet = DAContentAccess.CAEndOperation(hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
                }
                smsNode.Nodes.Clear();
                GetSMSMessages(GetCurrentDevice(), smsNode);
            }
        }

        //===================================================================
        // GetMeetingDescriptionLocationBuffer
        //
        // Fills meeting items in CA_DATA_ITEM struct and copies it to
        // unmanaged memory buffer
        //
        //===================================================================
        private IntPtr GetMeetingDescriptionLocationBuffer(string strDescription, string strLocation, int iCount)
        {
            CAContentAccess.CADataDefinitions.CA_DATA_ITEM[] dataItem = new CADataDefinitions.CA_DATA_ITEM[iCount];
            
            int iIndex= 0;
            if (strDescription.Length > 0)
            {
                // Description
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CALENDAR;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_DESCRIPTION;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strDescription);
                iIndex += 1;
            }
            if (strLocation.Length > 0)
            {
                // Location
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CALENDAR;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_LOCATION;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strLocation);
                iIndex += 1;
            }
            // Allocate memory for buffer
            int iSize = iCount * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
            IntPtr bufDataItem = Marshal.AllocHGlobal(iSize);
            for (iIndex = 0; iIndex < iCount; iIndex++)
            {
                // Calculate beginning of CA_DATA_ITEM structure of item 'iIndex'
                Int64 iPtr = bufDataItem.ToInt64() + iIndex * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                // Convert integer to pointer
                IntPtr ptr = new IntPtr(iPtr);
                Marshal.StructureToPtr(dataItem[iIndex], ptr, true);
            }
            return bufDataItem;
        }

        //===================================================================
        // GetCallNameNumberBuffer
        //
        // Fills meeting items in CA_DATA_ITEM struct and copies it to
        // unmanaged memory buffer
        //
        //===================================================================
        private IntPtr GetCallNameNumberBuffer(string strName, string strNumber, int iCount)
        {
            CAContentAccess.CADataDefinitions.CA_DATA_ITEM[] dataItem = new CADataDefinitions.CA_DATA_ITEM[iCount];
            
            int iIndex=0;
            if (strName.Length > 0)
            {
                // Name
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CALENDAR;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_DESCRIPTION;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strName);
                iIndex += 1;
            }
            if (strNumber.Length > 0)
            {
                // Number
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CALENDAR;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_ITEM_DATA;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strNumber);
                iIndex += 1;
            }
            // Allocate memory for buffer
            int iSize = iCount * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
            IntPtr bufDataItem = Marshal.AllocHGlobal(iSize);
            for (iIndex = 0; iIndex < iCount; iIndex++)
            {
                // Calculate beginning of CA_DATA_ITEM structure of item 'iIndex'
                Int64 iPtr = bufDataItem.ToInt64() + iIndex * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                // Convert integer to pointer
                IntPtr ptr = new IntPtr(iPtr);
                Marshal.StructureToPtr(dataItem[iIndex], ptr, true);
            }
            return bufDataItem;
        }

        //===================================================================
        // GetBirthDayNameYearBuffer
        //
        // Fills meeting items in CA_DATA_ITEM struct and copies it to
        // unmanaged memory buffer
        //
        //===================================================================
        private IntPtr GetBirthDayNameYearBuffer(string strName, string strYear, int iCount)
        {
            CAContentAccess.CADataDefinitions.CA_DATA_ITEM[] dataItem = new CADataDefinitions.CA_DATA_ITEM[iCount];

            int iIndex=0;
            if (strName.Length > 0)
            {
                // Description
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CALENDAR;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_DESCRIPTION;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strName);
                iIndex += 1;
            }
            if (strYear.Length > 0)
            {
                // Location
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CALENDAR;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_ITEM_DATA;
                Int32 dwYear = Int32.Parse(strYear);
                dataItem[iIndex].pCustomData = new IntPtr(dwYear);
                iIndex += 1;
            }
            // Allocate memory for buffer
            int iSize = iCount * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
            IntPtr bufDataItem = Marshal.AllocHGlobal(iSize);
            for (iIndex = 0; iIndex < iCount; iIndex++)
            {
                // Calculate beginning of CA_DATA_ITEM structure of item 'iIndex'
                Int64 iPtr = bufDataItem.ToInt64() + iIndex * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                // Convert integer to pointer
                IntPtr ptr = new IntPtr(iPtr);
                Marshal.StructureToPtr(dataItem[iIndex], ptr, true);
            }
            return bufDataItem;
        }


        //===================================================================
        // GetMemoBuffer
        //
        // Fills meeting items in CA_DATA_ITEM struct and copies it to
        // unmanaged memory buffer
        //
        //===================================================================
        private IntPtr GetMemoBuffer(string strMemo, int iCount)
        {
            CAContentAccess.CADataDefinitions.CA_DATA_ITEM[] dataItem = new CADataDefinitions.CA_DATA_ITEM[iCount];
            int iIndex =0;
            if (strMemo.Length > 0)
            {
                // Description
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CALENDAR;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_DESCRIPTION;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strMemo);
                iIndex += 1;
            }
            // Allocate memory for buffer
            int iSize = iCount * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
            IntPtr bufDataItem = Marshal.AllocHGlobal(iSize);
            for (iIndex = 0; iIndex < iCount; iIndex++)
            {
                // Calculate beginning of CA_DATA_ITEM structure of item 'iIndex'
                Int64 iPtr = bufDataItem.ToInt64() + iIndex * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                // Convert integer to pointer
                IntPtr ptr = new IntPtr(iPtr);
                Marshal.StructureToPtr(dataItem[iIndex], ptr, true);
            }
            return bufDataItem;
        }

        //===================================================================
        // GetTodoBuffer
        //
        // Fills meeting items in CA_DATA_ITEM struct and copies it to
        // unmanaged memory buffer
        //
        //===================================================================
        private IntPtr GetTodoBuffer(string strTodo, int iTodoPriority, int iTodoAction, int iCount)
        {
            CAContentAccess.CADataDefinitions.CA_DATA_ITEM[] dataItem = new CADataDefinitions.CA_DATA_ITEM[iCount];
            
            int iIndex=0;
            if (strTodo.Length > 0)
            {
                // Description
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CALENDAR;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_DESCRIPTION;
                dataItem[iIndex].pCustomData = Marshal.StringToCoTaskMemUni(strTodo);
                iIndex += 1;
            }
            if (iTodoPriority > 0)
            {
                // Prt
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CALENDAR;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_TODO_PRIORITY;
                dataItem[iIndex].pCustomData = new IntPtr(iTodoPriority);
                iIndex += 1;
            }
            if (iTodoAction > 0)
            {
                // Description
                dataItem[iIndex].iSize = Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                dataItem[iIndex].iFieldType = CADataDefinitions.CA_FIELD_TYPE_CALENDAR;
                dataItem[iIndex].iFieldSubType = CADataDefinitions.CA_FIELD_SUB_TYPE_TODO_STATUS;
                dataItem[iIndex].pCustomData = new IntPtr(iTodoAction);
                iIndex += 1;
            }
            // Allocate memory for buffer
            int iSize = iCount * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
            IntPtr bufDataItem = Marshal.AllocHGlobal(iSize);
            for (iIndex = 0; iIndex < iCount; iIndex++)
            {
                // Calculate beginning of CA_DATA_ITEM structure of item 'iIndex'
                Int64 iPtr = bufDataItem.ToInt64() + iIndex * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                // Convert integer to pointer
                IntPtr ptr = new IntPtr(iPtr);
                Marshal.StructureToPtr(dataItem[iIndex], ptr, true);
            }
            return bufDataItem;
        }

        //===================================================================
        // FreeCalendarDataAllocations
        //
        // Free's gobal memory allocated for clandar write
        //
        //===================================================================
        private void FreeCalendarDataAllocations(CAContentAccess.CADataDefinitions.CA_DATA_CALENDAR dataCalendar)
        {
            IntPtr pDataItem = dataCalendar.pDataItems;
            byte iItemCount = dataCalendar.bItemCount;
            if (iItemCount > 0)
            {
                for (int iIndex = 0; iIndex < iItemCount; iIndex++)
                {
                    CAContentAccess.CADataDefinitions.CA_DATA_ITEM dataItem = (CAContentAccess.CADataDefinitions.CA_DATA_ITEM)Marshal.PtrToStructure(new IntPtr(pDataItem.ToInt64() + iIndex * Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM))), typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                    if (dataItem.iFieldSubType != CADataDefinitions.CA_FIELD_SUB_TYPE_TODO_PRIORITY & dataItem.iFieldSubType != CADataDefinitions.CA_FIELD_SUB_TYPE_TODO_STATUS)
                    {
                        if (dataItem.iFieldSubType == CADataDefinitions.CA_FIELD_SUB_TYPE_ITEM_DATA)
                        {
                            if (dataCalendar.iInfoField != CADataDefinitions.CA_CALENDAR_ITEM_BIRTHDAY)
                            {
                                Marshal.FreeCoTaskMem(dataItem.pCustomData);
                            }
                        }
                        else
                        {
                            Marshal.FreeCoTaskMem(dataItem.pCustomData);
                        }
                    }
                }
            }
            Marshal.FreeHGlobal(pDataItem);
        }

        //===================================================================
        // ShowNewCalendarDlg
        //
        // Shows "New Calendar item" dialog and writes Calendar entry to device
        //
        //===================================================================
        private void ShowNewCalendarDlg()
        {
            // Open "New Text Message" dialog
            CalendarItemDlg dlg = new CalendarItemDlg();
            if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }
            CheckCalendarConnection(GetCurrentDevice());
            CAContentAccess.CADataDefinitions.CA_DATA_CALENDAR dataCalendar = new CADataDefinitions.CA_DATA_CALENDAR();
            dataCalendar.iSize = Marshal.SizeOf(dataCalendar);
            dataCalendar.iInfoField = CADataDefinitions.CA_CALENDAR_ITEM_MEETING + dlg.ComboBoxType.SelectedIndex;

            ConvertToPIMDate(dlg.DTPickerNoteBeginDate.Value,ref dataCalendar.noteStartDate);
            ConvertToPIMDate(dlg.DTPickerNoteEndDate.Value,ref  dataCalendar.noteEndDate);
            dataCalendar.iAlarmState = CADataDefinitions.CA_CALENDAR_ALARM_NOT_SET + dlg.ComboAlarm.SelectedIndex;
            if ((dataCalendar.iAlarmState == CADataDefinitions.CA_CALENDAR_ALARM_NOT_SET))
            {
                GetEmptyPIMDate(ref dataCalendar.noteAlarmTime);
            }
            else
            {
                ConvertToPIMDate(dlg.DTPickerAlarmDate.Value, ref dataCalendar.noteAlarmTime);
            }
            dataCalendar.iRecurrence = CADataDefinitions.CA_CALENDAR_RECURRENCE_NONE + dlg.ComboRecurrence.SelectedIndex;
            if ((dataCalendar.iRecurrence == CADataDefinitions.CA_CALENDAR_RECURRENCE_NONE))
            {
                GetEmptyPIMDate(ref dataCalendar.recurrenceEndDate);
            }
            else
            {
                CADataDefinitions.CA_SET_RECURRENCE_INTERVAL(ref dataCalendar.iRecurrence, 1);
                if (dlg.CheckBoxRecEnd.Checked)
                {
                    ConvertToPIMDate(dlg.DTPickerAlarmDate.Value,ref dataCalendar.recurrenceEndDate);
                }
                else
                {
                    GetEmptyPIMDate(ref dataCalendar.recurrenceEndDate);
                }
            }

            if (dataCalendar.iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_MEETING)
            {
                int iCount = 0;
                if (dlg.TextBoxNote.Text.Length > 0)
                {
                    iCount += 1;
                }
                if (dlg.TextBoxLocation.Text.Length > 0)
                {
                    iCount += 1;
                }
                dataCalendar.bItemCount = (byte)iCount;
                dataCalendar.pDataItems = GetMeetingDescriptionLocationBuffer(dlg.TextBoxNote.Text, dlg.TextBoxLocation.Text, iCount);
            }
            else if (dataCalendar.iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_CALL)
            {
                int iCount = 0;
                if (dlg.TextBoxNote.Text.Length > 0)
                {
                    iCount += 1;
                }
                if (dlg.TextBoxLocation.Text.Length > 0)
                {
                    iCount += 1;
                }
                dataCalendar.bItemCount = (byte)iCount;
                dataCalendar.pDataItems = GetCallNameNumberBuffer(dlg.TextBoxNote.Text, dlg.TextBoxLocation.Text, iCount);
            }
            else if (dataCalendar.iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_BIRTHDAY)
            {
                int iCount = 0;
                if (dlg.TextBoxNote.Text.Length > 0)
                {
                    iCount += 1;
                }
                if (dlg.TextBoxLocation.Text.Length > 0)
                {
                    iCount += 1;
                }
                dataCalendar.bItemCount = (byte)iCount;
                dataCalendar.pDataItems = GetBirthDayNameYearBuffer(dlg.TextBoxNote.Text, dlg.TextBoxLocation.Text, iCount);
            }
            else if (dataCalendar.iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_MEMO)
            {
                int iCount = 0;
                if (dlg.TextBoxNote.Text.Length > 0)
                {
                    iCount += 1;
                }
                dataCalendar.bItemCount = (byte)iCount;
                dataCalendar.pDataItems = GetMemoBuffer(dlg.TextBoxNote.Text, iCount);
            }
            else if (dataCalendar.iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_REMINDER)
            {
                int iCount = 0;
                if (dlg.TextBoxNote.Text.Length > 0)
                {
                    iCount += 1;
                }
                dataCalendar.bItemCount = (byte)iCount;
                // reuse getmemobuffer function
                dataCalendar.pDataItems = GetMemoBuffer(dlg.TextBoxNote.Text, iCount);
            }
            else if (dataCalendar.iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_NOTE)
            {
                int iCount = 0;
                if (dlg.TextBoxNote.Text.Length > 0)
                {
                    iCount += 1;
                }
                dataCalendar.bItemCount = (byte)iCount;
                // reuse getmemobuffer function
                dataCalendar.pDataItems = GetMemoBuffer(dlg.TextBoxNote.Text, iCount);
            }
            else if (dataCalendar.iInfoField == CADataDefinitions.CA_CALENDAR_ITEM_TODO)
            {
                int iTodoPriority = dlg.ComboTodoPrior.SelectedIndex + CADataDefinitions.CA_CALENDAR_TODO_PRIORITY_HIGH;
                int iTodoAction = dlg.ComboTodoAction.SelectedIndex + CADataDefinitions.CA_CALENDAR_TODO_STATUS_NEEDS_ACTION;
                int iCount = 0;
                if (iTodoPriority > 0)
                {
                    iCount += 1;
                }
                if (iTodoAction > 0)
                {
                    iCount += 1;
                }
                if (dlg.TextBoxNote.Text.Length > 0)
                {
                    iCount += 1;
                }
                dataCalendar.bItemCount = (byte)iCount;
                dataCalendar.pDataItems = GetTodoBuffer(dlg.TextBoxNote.Text, iTodoPriority, iTodoAction, iCount);
            }
            
            System.Windows.Forms.TreeNode calendarNode;
            if (TVW_Navigator.SelectedNode.ImageIndex == m_iIconCalendarIndex)
                calendarNode = TVW_Navigator.SelectedNode;
            else
                calendarNode = TVW_Navigator.SelectedNode.Parent;
            DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;
            folderInfo = MapCAFolderInfoToCFI((CAFolderInfo)calendarNode.Tag);

            // Write new Calendar item to currently connected device
            int hOperHandle = 0;
            int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0,ref hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
            }
            CAContentAccess.DAContentAccess.CARegisterOperationCallback(hOperHandle, CONADefinitions.API_REGISTER, pCAOperationCallback);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterOperationCallback", iRet);
            CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID itemUid = new DAContentAccessDefinitions.CA_ITEM_ID();
            itemUid.iSize = Marshal.SizeOf(itemUid);
            itemUid.iFolderId = folderInfo.iFolderId;
            itemUid.iStatus = 0;
            itemUid.iTemporaryID = 0;
            itemUid.iUidLen = 0;
            itemUid.pbUid = IntPtr.Zero;
            IntPtr buf = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID)));
            Marshal.StructureToPtr(itemUid, buf, true);
            // Allocate memory for buffer
            IntPtr buf2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_CALENDAR)));
            Marshal.StructureToPtr(dataCalendar, buf2, true);
            iRet = DAContentAccess.CAWriteItem(hOperHandle, buf, 0, CADataDefinitions.CA_DATA_FORMAT_STRUCT, buf2);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAWriteItem", iRet);
            Marshal.FreeHGlobal(buf2);
            Marshal.FreeHGlobal(buf);

            FreeCalendarDataAllocations(dataCalendar);

            iRet = DAContentAccess.CACommitOperations(hOperHandle, IntPtr.Zero);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CACommitOperations", iRet);
            }
            CAContentAccess.DAContentAccess.CARegisterOperationCallback(hOperHandle, CONADefinitions.API_UNREGISTER, pCAOperationCallback);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterOperationCallback", iRet);
            iRet = DAContentAccess.CAEndOperation(hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
            }
            calendarNode.Nodes.Clear();
            GetCalendar(GetCurrentDevice(), calendarNode);
        }

        //===================================================================
        // ShowNewBookmarkDlg
        //
        // Shows "New Text Message" dialog and writes SMS to device
        //
        //===================================================================
        private void ShowNewBookmarkDlg()
        {
            // Open "New Bookmark" dialog
            BookmarkDlg dlg = new BookmarkDlg();
            if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }
            //
            CheckBookmarkConnection(GetCurrentDevice());
            //
            CAContentAccess.CADataDefinitions.CA_DATA_BOOKMARK dataBookmark = new CAContentAccess.CADataDefinitions.CA_DATA_BOOKMARK();
            dataBookmark.iSize = Marshal.SizeOf(dataBookmark);

            dataBookmark.pstrTitle = dlg.TextTitle.Text;
            dataBookmark.pstrBookMarkUrl = dlg.TextURL.Text;
            dataBookmark.pstrUrlShortcut = dlg.TextShort.Text;

            System.Windows.Forms.TreeNode bookmarksNode;
            if (TVW_Navigator.SelectedNode.ImageIndex == m_iIconBookmarkIndex)
                bookmarksNode = TVW_Navigator.SelectedNode;
            else
                bookmarksNode = TVW_Navigator.SelectedNode.Parent;
            CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;
            folderInfo = MapCAFolderInfoToCFI((CAFolderInfo)bookmarksNode.Tag);
            // Write new Bookmark item to currently connected device
            int hOperHandle = 0;
            int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0,ref  hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
            }
            CAContentAccess.DAContentAccess.CARegisterOperationCallback(hOperHandle, CONADefinitions.API_REGISTER, pCAOperationCallback);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterOperationCallback", iRet);
            CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID itemUid = new DAContentAccessDefinitions.CA_ITEM_ID();
            itemUid.iSize = Marshal.SizeOf(itemUid);
            itemUid.iFolderId = folderInfo.iFolderId;
            itemUid.iFolderId = folderInfo.iFolderId;
            itemUid.iStatus = 0;
            itemUid.iTemporaryID = 0;
            itemUid.iUidLen = 0;
            itemUid.pbUid = IntPtr.Zero;
            IntPtr buf = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID)));
            Marshal.StructureToPtr(itemUid, buf, true);
            // Allocate memory for buffer
            IntPtr buf2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.CADataDefinitions.CA_DATA_BOOKMARK)));
            Marshal.StructureToPtr(dataBookmark, buf2, true);
            iRet = DAContentAccess.CAWriteItem(hOperHandle, buf, 0, CADataDefinitions.CA_DATA_FORMAT_STRUCT, buf2);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAWriteItem", iRet);
            // Free memory allocated by DA API
            iRet = DAContentAccess.CAFreeItemData(m_hCurrentConnection, CADataDefinitions.CA_DATA_FORMAT_STRUCT, buf2);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iRet);
            Marshal.FreeHGlobal(buf2);
            Marshal.FreeHGlobal(buf);
            iRet = DAContentAccess.CACommitOperations(hOperHandle, IntPtr.Zero);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CACommitOperations", iRet);
            }
            CAContentAccess.DAContentAccess.CARegisterOperationCallback(hOperHandle, CONADefinitions.API_UNREGISTER, pCAOperationCallback);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterOperationCallback", iRet);
            iRet = DAContentAccess.CAEndOperation(hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
            }
            bookmarksNode.Nodes.Clear();
            GetBookmarks(GetCurrentDevice(), bookmarksNode);
        }

        //===================================================================
        // UninitializePCSAPI
        //
        // Uninitialize Nokia PC Connectivity API
        //
        //===================================================================
        private void UninitializePCSAPI()
        {
            try
            {
                // Unregister device notification callback function
                int iResult = CONADeviceManagement.CONARegisterNotifyCallback(m_hDMHandle, PCCSTypeDefinitions.API_UNREGISTER, pDeviceCallBack);
                if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CONARegisterNotifyCallback", iResult);
                // Close device management handle
                iResult = CONADeviceManagement.CONACloseDM(m_hDMHandle);
                if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CONACloseDM", iResult);
                // Uninitialize Device Management API
                iResult = CONADeviceManagement.DMAPI_Terminate(0);
                // Uninitialize Content Access API
                iResult = DAContentAccess.CAAPI_Terminate(0);
                if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CONAUninitialize", iResult);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString(), "Exception in UninitializePCSAPI");
            }
        }

        //===================================================================
        // PIMNavigator_Load
        //
        // Initialization of PIM Navigator dialog
        //
        //===================================================================
        private void PIMNavigator_Load(object sender, System.EventArgs e)
        {
            InitializePhoneAPI();
        }

        private void InitializePhoneAPI()
        {
            Timer1.Enabled = true;
            Timer1.Start();
            pCANotifyCallBack = CANotifyCallBack;
            pCAOperationCallback = CAOperationCallback;
            // Initialize Device Management APi
            int iResult = CONADeviceManagement.DMAPI_Initialize(CONADeviceManagement.DMAPI_VERSION_32, 0);
            // Initialize Data Access API
            iResult = DAContentAccess.CAAPI_Initialize(DAContentAccess.CAAPI_VERSION_30, 0);

            // Get Device management handle
            iResult = CONADeviceManagement.CONAOpenDM(ref m_hDMHandle);
            if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CONAOpenDM", iResult);

            //RefreshTreeView()
            bRefresh = true;
            // Register device notification callback function
            pDeviceCallBack = DeviceNotifyCallback;
            iResult = CONADeviceManagement.CONARegisterNotifyCallback(m_hDMHandle, CONADefinitions.API_REGISTER, pDeviceCallBack);
            if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CONARegisterNotifyCallback", iResult);
        }

        //===================================================================
        // BTN_New_Click
        //
        // User has clicked "New" button
        //
        //===================================================================
        private void BTN_New_Click(object sender, System.EventArgs e)
        {
            if (m_hCurrentConnection == m_hContacts)
            {
                ShowNewContactDlg();
            }
            else if (m_hCurrentConnection == m_hBookmark)
            {
                ShowNewBookmarkDlg();
            }
            else if (m_hCurrentConnection == m_hCalendar)
            {
                ShowNewCalendarDlg();
            }
            else
            {
                ShowNewSMSDlg();
            }
        }

        //===================================================================
        // BTN_Delete_Click
        //
        // User has clicked "Delete" button
        //
        //===================================================================
        private void BTN_Delete_Click(object sender, System.EventArgs e)
        {
            if (MessageBox.Show("Are you sure you want to delete selected item?", "Confirm Item Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                int hOperHandle = 0;
                int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0,ref  hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
                }
                // Deletes PIM item from currently connected device
                CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID = new DAContentAccessDefinitions.CA_ITEM_ID();
                CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO CFI = new CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO();
                bool bFolder = false;
                IntPtr buffer = IntPtr.Zero;
                if (object.ReferenceEquals(TVW_Navigator.SelectedNode.Tag.GetType(), typeof(CAItemID)))
                {
                    UID = MapCAItemIDToUID((CAItemID)TVW_Navigator.SelectedNode.Tag);
                    UID.iSize = Marshal.SizeOf(UID);
                }
                else
                {
                    bFolder = true;
                    CFI = MapCAFolderInfoToCFI((CAFolderInfo)TVW_Navigator.SelectedNode.Tag);
                    CFI.iSize = Marshal.SizeOf(CFI);
                }
                if (bFolder)
                {
                    buffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO)));
                    Marshal.StructureToPtr(CFI, buffer, true);
                    iRet = DAContentAccess.CADeleteFolder(hOperHandle, buffer);
                }
                else
                {
                    buffer = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
                    Marshal.StructureToPtr(UID, buffer, true);
                    iRet = DAContentAccess.CADeleteItem(hOperHandle, buffer, 0);
                }
                if (iRet == PCCSErrors.CONA_OK)
                {
                    // Delete item from tree view
                    TVW_Navigator.SelectedNode.Remove();
                }
                else
                {
                    PCCAPIUtils.ShowErrorMessage("DADeleteItem", iRet);
                }
                Marshal.FreeHGlobal(buffer);

                iRet = DAContentAccess.CACommitOperations(hOperHandle, IntPtr.Zero);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CACommitOperations", iRet);
                }

                iRet = DAContentAccess.CAEndOperation(hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
                }

                if (!bFolder)
                {
                    FreeUIDMappingMemory(UID);
                }
            }
        }

        //===================================================================
        // BTN_Refresh_Click
        //
        // User has clicked "Refresh" button
        //
        //===================================================================
        private void BTN_Refresh_Click(object sender, System.EventArgs e)
        {
            // Fill connected devices, target folders and PIM items in tree view
            //RefreshTreeView()
            bRefresh = true;
        }

        //===================================================================
        // BTN_Close_Click
        //
        // User has clicked "Close" button
        //
        //===================================================================
        private void BTN_Close_Click(object sender, System.EventArgs e)
        {
            Close();
        }

        //===================================================================
        // Timer1_Tick
        //
        // Handles timer events.
        // Timer is used to start RefreshTreeView() asynchronously
        //
        //===================================================================
        private void Timer1_Tick(object sender, System.EventArgs e)
        {
            if ((bRefresh))
            {
                bRefresh = false;
                // Fill connected devices, target folders and PIM items in tree view
                RefreshTreeView();
            }
        }

        //===================================================================
        // GetUidFromBuffer
        //
        // Retrieves UID from unmanaged memory buffer
        //
        //===================================================================
        private CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID GetUidFromBuffer(int iIndex, IntPtr pUIds)
        {
            // Calculate beginning of item 'iIndex'
            Int64 iPtr = pUIds.ToInt64() + (iIndex * Marshal.SizeOf(typeof(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID)));
            // Convert integer to pointer
            IntPtr ptr = new IntPtr(iPtr);
            // Copy data from buffer
            return (CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID)Marshal.PtrToStructure(ptr, typeof(CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID));
        }

        //===================================================================
        // GetContacts
        //
        // Reads contact items from phone and adds them into tree view.
        //
        //===================================================================
        private void GetContacts(string strSerialNumber, System.Windows.Forms.TreeNode parentItem)
        {
            // Check PIM connection to contacts folder and open it if needed
            int iRet = CheckContactsConnection(strSerialNumber);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Set contacts folder target path
                CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo = MapCAFolderInfoToCFI((CAFolderInfo)parentItem.Tag);
                // Read all the contact item IDs from the connected device 
                CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST caIDList = new DAContentAccessDefinitions.CA_ID_LIST();
                caIDList.iSize = Marshal.SizeOf(caIDList);
                IntPtr buf = Marshal.AllocHGlobal(Marshal.SizeOf(caIDList));
                Marshal.StructureToPtr(caIDList, buf, true);
                iRet = DAContentAccess.CAGetIDList(m_hContacts, folderInfo.iFolderId, 0, buf);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAGetIDList", iRet);
                }
                caIDList = (CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST)Marshal.PtrToStructure(buf, typeof(CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST));
                int hOperHandle = 0;
                iRet = DAContentAccess.CABeginOperation(m_hContacts, 0, ref hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
                }
                bool bErrorShown = false;
                int k;
                for (k = 0; k < caIDList.iUIDCount; k++)
                {
                    // Read contact item from the connected device
                    CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID = GetUidFromBuffer(k, caIDList.pUIDs);

                    IntPtr bufId = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
                    Marshal.StructureToPtr(UID, bufId, true);
                    // UID.iSize = Marshal.SizeOf(UID)
                    CAContentAccess.CADataDefinitions.CA_DATA_CONTACT dataContact = new CADataDefinitions.CA_DATA_CONTACT();
                    dataContact.iSize = Marshal.SizeOf(dataContact);
                    dataContact.bPICount = 0;
                    dataContact.pPIFields = IntPtr.Zero;
                    dataContact.bAddressCount = 0;
                    dataContact.pAddressFields = IntPtr.Zero;
                    dataContact.bNumberCount = 0;
                    dataContact.pNumberFields = IntPtr.Zero;
                    dataContact.bGeneralCount = 0;
                    dataContact.pGeneralFields = IntPtr.Zero;
                    IntPtr bufData = Marshal.AllocHGlobal(Marshal.SizeOf(dataContact));
                    Marshal.StructureToPtr(dataContact, bufData, true);
                    iRet = DAContentAccess.CAReadItem(hOperHandle, bufId, DAContentAccessDefinitions.CA_OPTION_USE_CACHE, CADataDefinitions.CA_DATA_FORMAT_STRUCT, bufData);
                    //iRet = CAReadItem(hOperHandle, bufId, 0, CA_DATA_FORMAT_STRUCT, bufData)
                    if (iRet == PCCSErrors.CONA_OK)
                    {
                        dataContact = (CAContentAccess.CADataDefinitions.CA_DATA_CONTACT)Marshal.PtrToStructure(bufData, typeof(CAContentAccess.CADataDefinitions.CA_DATA_CONTACT));
                        if (dataContact.bPICount > 0)
                        {
                            // Insert contact item in tree view
                            System.Windows.Forms.TreeNode itemZ = new System.Windows.Forms.TreeNode();
                            itemZ.ImageIndex = m_iIconContactIndex;
                            itemZ.SelectedImageIndex = m_iIconContactIndex;
                            itemZ.Tag = MapUIDToCAItemID(UID);
                            if (dataContact.bPICount > 0)
                            {
                                CAContentAccess.CADataDefinitions.CA_DATA_ITEM itemData;
                                itemData = (CAContentAccess.CADataDefinitions.CA_DATA_ITEM)Marshal.PtrToStructure(dataContact.pPIFields, typeof(CAContentAccess.CADataDefinitions.CA_DATA_ITEM));
                                itemZ.Text = Marshal.PtrToStringUni(itemData.pCustomData);
                            }
                            parentItem.Nodes.Add(itemZ);
                        }
                    }
                    else
                    {
                        PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
                        break; // TODO: might not be correct. Was : Exit For
                        // Reading failed, quit loop.
                    }
                    // Free memory allocated by DA API
                    int iResult = DAContentAccess.CAFreeItemData(m_hContacts, CADataDefinitions.CA_DATA_FORMAT_STRUCT, bufData);
                    if (iResult != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iResult);
                    Marshal.FreeHGlobal(bufData);
                    bufData = IntPtr.Zero;
                    Marshal.FreeHGlobal(bufId);
                    bufId = IntPtr.Zero;
                }
                iRet = DAContentAccess.CAEndOperation(hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
                }
                iRet = DAContentAccess.CAFreeIdListStructure(buf);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAFreeIdListStructure", iRet);
                }
                Marshal.FreeHGlobal(buf);
            }
        }

        //===================================================================
        // GetSMSMessages
        //
        // Reads SMS messages from phone and adds them into tree view.
        //
        //===================================================================
        private void GetSMSMessages(string strSerialNumber, System.Windows.Forms.TreeNode parentItem)
        {
            // Check PIM connection to SMS folders and open it if needed
            int iRet = CheckSMSConnection(strSerialNumber);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Set SMS folder target path
                DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo = MapCAFolderInfoToCFI((CAFolderInfo)parentItem.Tag);
                if (folderInfo.iFolderId == 0)
                {
                    return;
                    // SMS root folder
                }
                // Read all the SMS item IDs from the connected device 
                CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST caIDList = new DAContentAccessDefinitions.CA_ID_LIST();
                caIDList.iSize = Marshal.SizeOf(caIDList);
                IntPtr buf = Marshal.AllocHGlobal(Marshal.SizeOf(caIDList));
                Marshal.StructureToPtr(caIDList, buf, true);
                iRet = DAContentAccess.CAGetIDList(m_hSMS, folderInfo.iFolderId, 0, buf);
                // With messages, ECONA_NOT_FOUND is "OK" return value in some situations
                // (item exists, but phone/library is not ready yet)
                if ((iRet != PCCSErrors.CONA_OK) & (iRet != PCCSErrors.ECONA_NOT_FOUND))
                {
                    PCCAPIUtils.ShowErrorMessage("CAGetIDList", iRet);
                }
                caIDList = (CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST)Marshal.PtrToStructure(buf, typeof(CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST));
                int hOperHandle = 0;
                iRet = DAContentAccess.CABeginOperation(m_hSMS, 0, ref hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
                }
                bool bErrorShown = false;
                int k;
                for (k = 0; k < caIDList.iUIDCount; k++)
                {
                    // Read SMS item from the connected device
                    DAContentAccessDefinitions.CA_ITEM_ID UID = GetUidFromBuffer(k, caIDList.pUIDs);

                    IntPtr bufId = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
                    Marshal.StructureToPtr(UID, bufId, true);
                    CAContentAccess.CADataDefinitions.CA_DATA_MSG dataSMS = new CADataDefinitions.CA_DATA_MSG();
                    dataSMS.iSize = Marshal.SizeOf(dataSMS);
                    dataSMS.bAddressCount = 0;
                    dataSMS.iDataLength = 0;
                    dataSMS.iInfoField = 0;
                    dataSMS.pAddress = IntPtr.Zero;
                    dataSMS.pbData = IntPtr.Zero;
                    GetEmptyPIMDate(ref dataSMS.messageDate);
                    IntPtr bufData = Marshal.AllocHGlobal(dataSMS.iSize);
                    Marshal.StructureToPtr(dataSMS, bufData, true);
                    iRet = DAContentAccess.CAReadItem(hOperHandle, bufId, DAContentAccessDefinitions.CA_OPTION_USE_CACHE, CADataDefinitions.CA_DATA_FORMAT_STRUCT, bufData);
                    if (iRet == PCCSErrors.CONA_OK)
                    {
                        dataSMS = (CAContentAccess.CADataDefinitions.CA_DATA_MSG)Marshal.PtrToStructure(bufData, typeof(CAContentAccess.CADataDefinitions.CA_DATA_MSG));
                        if (dataSMS.iDataLength > 0)
                        {
                            if ((CADataDefinitions.CA_GET_DATA_FORMAT(dataSMS.iInfoField)) == CADataDefinitions.CA_DATA_FORMAT_UNICODE)
                            {
                                if (!IntPtr.Zero.Equals(dataSMS.pbData))
                                {
                                    // Insert SMS message item in tree view
                                    System.Windows.Forms.TreeNode itemZ = new System.Windows.Forms.TreeNode();
                                    string strData = Marshal.PtrToStringUni(dataSMS.pbData, dataSMS.iDataLength / 2);
                                    itemZ.Text = strData;
                                    itemZ.ImageIndex = m_iIconSMSIndex;
                                    itemZ.SelectedImageIndex = m_iIconSMSIndex;
                                    itemZ.Tag = MapUIDToCAItemID(UID);
                                    parentItem.Nodes.Add(itemZ);
                                }
                                else
                                {
                                    // No data, GMS or other kind of message?
                                }
                            }
                            else
                            {
                                // Message in data format
                            }
                        }
                    }
                    else
                    {
                        PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
                        break; // TODO: might not be correct. Was : Exit For
                        // Reading failed, quit loop.
                    }
                    // Free memory allocated by DA API
                    iRet = DAContentAccess.CAFreeItemData(m_hSMS, CADataDefinitions.CA_DATA_FORMAT_STRUCT, bufData);
                    if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iRet);

                    Marshal.FreeHGlobal(bufData);
                    Marshal.FreeHGlobal(bufId);
                }
                iRet = DAContentAccess.CAEndOperation(hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
                }
                iRet = DAContentAccess.CAFreeIdListStructure(buf);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAFreeIdListStructure", iRet);
                }
                Marshal.FreeHGlobal(buf);
            }
        }

        //===================================================================
        // GetMMSMessages
        //
        // Reads MMS messages from phone and adds them into tree view.
        //
        //===================================================================
        private void GetMMSMessages(string strSerialNumber, System.Windows.Forms.TreeNode parentItem)
        {
            // Check PIM connection to MMS folders and open it if needed
            int iRet = CheckMMSConnection(strSerialNumber);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Set MMS folder target path
                DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo = MapCAFolderInfoToCFI((CAFolderInfo)parentItem.Tag);
                if (folderInfo.iFolderId == 0)
                {
                    return;
                    // MMS root folder
                }
                // Read all the MMS item IDs from the connected device 
                CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST caIDList = new DAContentAccessDefinitions.CA_ID_LIST();
                caIDList.iSize = Marshal.SizeOf(caIDList);
                IntPtr buf = Marshal.AllocHGlobal(Marshal.SizeOf(caIDList));
                Marshal.StructureToPtr(caIDList, buf, true);
                iRet = DAContentAccess.CAGetIDList(m_hMMS, folderInfo.iFolderId, 0, buf);
                // With messages, ECONA_NOT_FOUND is "OK" return value in some situations
                // (item exists, but phone/library is not ready yet)
                if ((iRet != PCCSErrors.CONA_OK) & (iRet != PCCSErrors.ECONA_NOT_FOUND))
                {
                    PCCAPIUtils.ShowErrorMessage("CAGetIDList", iRet);
                }
                caIDList = (CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST)Marshal.PtrToStructure(buf, typeof(CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST));
                int hOperHandle = 0;
                iRet = DAContentAccess.CABeginOperation(m_hMMS, 0,ref  hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
                }
                bool bErrorShown = false;
                int k;
                for (k = 0; k < caIDList.iUIDCount; k++)
                {
                    // Read MMS item from the connected device
                    CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID = GetUidFromBuffer(k, caIDList.pUIDs);
                    IntPtr bufId = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
                    Marshal.StructureToPtr(UID, bufId, true);
                    CAContentAccess.CADataDefinitions.CA_MMS_DATA dataMMS = new CADataDefinitions.CA_MMS_DATA();
                    dataMMS.iSize = Marshal.SizeOf(dataMMS);
                    dataMMS.bAddressCount = 0;
                    dataMMS.iDataLength = 0;
                    dataMMS.iInfoField = 0;
                    dataMMS.pAddress = IntPtr.Zero;
                    dataMMS.pbData = IntPtr.Zero;
                    GetEmptyPIMDate(ref dataMMS.messageDate);
                    IntPtr bufData = Marshal.AllocHGlobal(Marshal.SizeOf(dataMMS));
                    Marshal.StructureToPtr(dataMMS, bufData, true);
                    iRet = DAContentAccess.CAReadItem(hOperHandle, bufId, DAContentAccessDefinitions.CA_OPTION_USE_CACHE, CADataDefinitions.CA_DATA_FORMAT_STRUCT, bufData);
                    if (iRet == PCCSErrors.CONA_OK)
                    {
                        dataMMS = (CAContentAccess.CADataDefinitions.CA_MMS_DATA)Marshal.PtrToStructure(bufData, typeof(CAContentAccess.CADataDefinitions.CA_MMS_DATA));
                        string strData = "";
                        System.DateTime dateMsg = new DateTime();
                        System.DateTime dateEmpty = new DateTime();
                        dateMsg = ConvertPIMDataDate(dataMMS.messageDate);
                        if (!dateMsg.Equals(dateEmpty))
                        {
                            strData = dateMsg.ToString();
                        }
                        if (dataMMS.bAddressCount > 0)
                        {
                            if (strData.Length > 0)
                            {
                                strData += ": ";
                            }
                            CAContentAccess.CADataDefinitions.CA_DATA_ADDRESS itemData;
                            itemData = (CAContentAccess.CADataDefinitions.CA_DATA_ADDRESS)Marshal.PtrToStructure(dataMMS.pAddress, typeof(CAContentAccess.CADataDefinitions.CA_DATA_ADDRESS));
                            strData += itemData.pstrAddress;
                        }
                        // Insert MMS message item in tree view
                        System.Windows.Forms.TreeNode itemZ = new System.Windows.Forms.TreeNode();
                        itemZ.Text = strData;
                        itemZ.ImageIndex = m_iIconMMSIndex;
                        itemZ.SelectedImageIndex = m_iIconMMSIndex;
                        itemZ.Tag = MapUIDToCAItemID(UID);
                        parentItem.Nodes.Add(itemZ);
                    }
                    else
                    {
                        PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
                        break; // TODO: might not be correct. Was : Exit For
                        // Reading failed, quit loop.
                    }
                    // Free memory allocated by DA API
                    iRet = DAContentAccess.CAFreeItemData(m_hMMS, CADataDefinitions.CA_DATA_FORMAT_STRUCT, bufData);
                    if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iRet);
                    Marshal.FreeHGlobal(bufData);
                    Marshal.FreeHGlobal(bufId);
                }
                iRet = DAContentAccess.CAEndOperation(hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
                }
                iRet = DAContentAccess.CAFreeIdListStructure(buf);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAFreeIdListStructure", iRet);
                }
                Marshal.FreeHGlobal(buf);
            }
        }

        //===================================================================
        // GetCalendar
        //
        // Reads calendar items from phone and adds them into tree view.
        //
        //===================================================================
        private void GetCalendar(string strSerialNumber, System.Windows.Forms.TreeNode parentItem)
        {
            // Check PIM connection to calendar folder and open it if needed
            int iRet = CheckCalendarConnection(strSerialNumber);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Set calendar folder target path
                CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo = MapCAFolderInfoToCFI((CAFolderInfo)parentItem.Tag);
                // Read all the calendar item IDs from the connected device 
                CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST caIDList = new DAContentAccessDefinitions.CA_ID_LIST();
                caIDList.iSize = Marshal.SizeOf(caIDList);
                IntPtr buf = Marshal.AllocHGlobal(Marshal.SizeOf(caIDList));
                Marshal.StructureToPtr(caIDList, buf, true);
                iRet = DAContentAccess.CAGetIDList(m_hCalendar, folderInfo.iFolderId, 0, buf);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAGetIDList", iRet);
                }
                caIDList = (CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST)Marshal.PtrToStructure(buf, typeof(CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST));
                int hOperHandle = 0;
                iRet = DAContentAccess.CABeginOperation(m_hCalendar, 0,ref  hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
                }
                bool bErrorShown = false;
                int k;
                for (k = 0; k < caIDList.iUIDCount; k++)
                {
                    // Read calendar item from the connected device
                    CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID = GetUidFromBuffer(k, caIDList.pUIDs);
                    IntPtr bufId = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
                    Marshal.StructureToPtr(UID, bufId, true);
                    CAContentAccess.CADataDefinitions.CA_DATA_CALENDAR dataCalendar = new CADataDefinitions.CA_DATA_CALENDAR();
                    dataCalendar.iSize = Marshal.SizeOf(dataCalendar);
                    dataCalendar.bItemCount = 0;
                    dataCalendar.iInfoField = 0;
                    dataCalendar.iRecurrence = 0;
                    dataCalendar.iAlarmState = 0;
                    GetEmptyPIMDate(ref dataCalendar.noteAlarmTime);
                    GetEmptyPIMDate(ref dataCalendar.noteEndDate);
                    GetEmptyPIMDate(ref dataCalendar.noteStartDate);
                    dataCalendar.pDataItems = IntPtr.Zero;
                    GetEmptyPIMDate(ref dataCalendar.recurrenceEndDate);
                    IntPtr bufData = Marshal.AllocHGlobal(Marshal.SizeOf(dataCalendar));
                    Marshal.StructureToPtr(dataCalendar, bufData, true);
                    iRet = DAContentAccess.CAReadItem(hOperHandle, bufId, DAContentAccessDefinitions.CA_OPTION_USE_CACHE, CADataDefinitions.CA_DATA_FORMAT_STRUCT, bufData);
                    if (iRet == PCCSErrors.CONA_OK)
                    {
                        dataCalendar = (CAContentAccess.CADataDefinitions.CA_DATA_CALENDAR)Marshal.PtrToStructure(bufData, typeof(CAContentAccess.CADataDefinitions.CA_DATA_CALENDAR));
                        string strData = "";
                        System.DateTime dateMsg = new DateTime();
                        System.DateTime dateEmpty = new DateTime();
                        dateMsg = ConvertPIMDataDate(dataCalendar.noteStartDate);
                        if (!dateMsg.Equals(dateEmpty))
                        {
                            strData = dateMsg.ToString() + ": ";
                        }
                        strData += CalendarItemType2String(dataCalendar.iInfoField);
                        System.Windows.Forms.TreeNode itemZ = new System.Windows.Forms.TreeNode();
                        itemZ.ImageIndex = m_iIconCalendarItemIndex;
                        itemZ.SelectedImageIndex = m_iIconCalendarItemIndex;
                        itemZ.Tag = MapUIDToCAItemID(UID);
                        itemZ.Text = strData;
                        parentItem.Nodes.Add(itemZ);
                    }
                    else
                    {
                        PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
                        break; // TODO: might not be correct. Was : Exit For
                        // Reading failed, quit loop.
                    }
                    // Free memory allocated by DA API
                    iRet = DAContentAccess.CAFreeItemData(m_hCalendar, CADataDefinitions.CA_DATA_FORMAT_STRUCT, bufData);
                    if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iRet);

                    Marshal.FreeHGlobal(bufData);
                    Marshal.FreeHGlobal(bufId);
                }
                iRet = DAContentAccess.CAEndOperation(hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
                }
                iRet = DAContentAccess.CAFreeIdListStructure(buf);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAFreeIdListStructure", iRet);
                }
                Marshal.FreeHGlobal(buf);
            }
        }

        //===================================================================
        // GetBookmarks
        //
        // Reads bookmark items from phone and adds them into tree view.
        //
        //===================================================================
        private void GetBookmarks(string strSerialNumber, System.Windows.Forms.TreeNode parentItem)
        {
            // Check PIM connection to calendar folder and open it if needed
            int iRet = CheckBookmarkConnection(strSerialNumber);
            if (iRet == PCCSErrors.CONA_OK)
            {
                // Set Bookmark folder target path
                CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo = MapCAFolderInfoToCFI((CAFolderInfo)parentItem.Tag);
                // Read all the Bookmark item IDs from the connected device 
                CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST caIDList = new DAContentAccessDefinitions.CA_ID_LIST();
                caIDList.iSize = Marshal.SizeOf(caIDList);
                IntPtr buf = Marshal.AllocHGlobal(Marshal.SizeOf(caIDList));
                Marshal.StructureToPtr(caIDList, buf, true);
                iRet = DAContentAccess.CAGetIDList(m_hBookmark, folderInfo.iFolderId, 0, buf);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAGetIDList", iRet);
                }
                caIDList = (CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST)Marshal.PtrToStructure(buf, typeof(CAContentAccess.DAContentAccessDefinitions.CA_ID_LIST));
                int hOperHandle = 0;
                iRet = DAContentAccess.CABeginOperation(m_hBookmark, 0, ref hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
                }
                bool bErrorShown = false;
                int k;
                for (k = 0; k < caIDList.iUIDCount; k++)
                {
                    // Read Bookmark item from the connected device
                    CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID = GetUidFromBuffer(k, caIDList.pUIDs);
                    IntPtr bufId = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
                    Marshal.StructureToPtr(UID, bufId, true);
                    CAContentAccess.CADataDefinitions.CA_DATA_BOOKMARK dataBookmark = new CAContentAccess.CADataDefinitions.CA_DATA_BOOKMARK();
                    dataBookmark.iSize = Marshal.SizeOf(dataBookmark);
                    dataBookmark.pstrBookMarkUrl = "";
                    dataBookmark.pstrTitle = "";
                    dataBookmark.pstrUrlShortcut = "";
                    IntPtr bufData = Marshal.AllocHGlobal(Marshal.SizeOf(dataBookmark));
                    Marshal.StructureToPtr(dataBookmark, bufData, true);
                    iRet = DAContentAccess.CAReadItem(hOperHandle, bufId, DAContentAccessDefinitions.CA_OPTION_USE_CACHE, CADataDefinitions.CA_DATA_FORMAT_STRUCT, bufData);
                    if (iRet == PCCSErrors.CONA_OK)
                    {
                        dataBookmark = (CAContentAccess.CADataDefinitions.CA_DATA_BOOKMARK)Marshal.PtrToStructure(bufData, typeof(CAContentAccess.CADataDefinitions.CA_DATA_BOOKMARK));
                        string strData = dataBookmark.pstrTitle;
                        strData += ": ";
                        strData += dataBookmark.pstrBookMarkUrl;
                        System.Windows.Forms.TreeNode itemZ = new System.Windows.Forms.TreeNode();
                        itemZ.ImageIndex = m_iIconBookmarkItemIndex;
                        itemZ.SelectedImageIndex = m_iIconBookmarkItemIndex;
                        itemZ.Tag = MapUIDToCAItemID(UID);
                        itemZ.Text = strData;
                        parentItem.Nodes.Add(itemZ);
                    }
                    else
                    {
                        PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
                        break; // TODO: might not be correct. Was : Exit For
                        // Reading failed, quit loop.
                    }
                    // Free memory allocated by DA API
                    iRet = DAContentAccess.CAFreeItemData(m_hBookmark, CADataDefinitions.CA_DATA_FORMAT_STRUCT, bufData);
                    if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iRet);

                    Marshal.FreeHGlobal(bufData);
                    Marshal.FreeHGlobal(bufId);
                }
                iRet = DAContentAccess.CAEndOperation(hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
                }
                iRet = DAContentAccess.CAFreeIdListStructure(buf);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAFreeIdListStructure", iRet);
                }
                Marshal.FreeHGlobal(buf);
            }
        }

        private void BTN_Save_Click(object sender, System.EventArgs e)
        {
            string strFilter;
            if (TVW_Navigator.SelectedNode.ImageIndex == m_iIconContactIndex)
            {
                strFilter = "vCard files (*.vcf)|*.vcf||";
            }
            else if (TVW_Navigator.SelectedNode.ImageIndex == m_iIconSMSIndex)
            {
                strFilter = "vMessage files (*.vmg)|*.vmg||";
            }
            else if (TVW_Navigator.SelectedNode.ImageIndex == m_iIconBookmarkItemIndex)
            {
                strFilter = "vBookmark files (*.vbk)|*.vbk||";
            }
            else if (TVW_Navigator.SelectedNode.ImageIndex == m_iIconCalendarItemIndex)
            {
                strFilter = "vCalendar files (*.vcs)|*.vcs||";
            }
            else if (TVW_Navigator.SelectedNode.ImageIndex == m_iIconMMSIndex)
            {
                strFilter = "MMS files (*.mms)|*.mms||";
            }
            else
            {
                return;
            }
            System.Windows.Forms.SaveFileDialog fileDlg = new System.Windows.Forms.SaveFileDialog();
            fileDlg.Filter = strFilter;
            if (fileDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                int hOperHandle =0;
                int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0, ref hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
                }
                // Read contact item data from device
                CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID UID = MapCAItemIDToUID((CAItemID)TVW_Navigator.SelectedNode.Tag);
                IntPtr bufId = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
                Marshal.StructureToPtr(UID, bufId, true);
                CAContentAccess.CADataDefinitions.CA_DATA_VERSIT dataVersit = new CADataDefinitions.CA_DATA_VERSIT();
                dataVersit.iSize = Marshal.SizeOf(dataVersit);
                IntPtr bufData = Marshal.AllocHGlobal(Marshal.SizeOf(dataVersit));
                Marshal.StructureToPtr(dataVersit, bufData, true);
                iRet = DAContentAccess.CAReadItem(hOperHandle, bufId, DAContentAccessDefinitions.CA_OPTION_USE_CACHE, CADataDefinitions.CA_DATA_FORMAT_VERSIT, bufData);
                if (iRet == PCCSErrors.CONA_OK)
                {
                    dataVersit = (CAContentAccess.CADataDefinitions.CA_DATA_VERSIT)Marshal.PtrToStructure(bufData, typeof(CAContentAccess.CADataDefinitions.CA_DATA_VERSIT));
                    byte[] bVersitObject = new byte[dataVersit.iDataLength];
            
                    Marshal.Copy(dataVersit.pbVersitObject, bVersitObject, 0, dataVersit.iDataLength);
                    System.IO.Stream ios = System.IO.File.Open(fileDlg.FileName, System.IO.FileMode.Create);
                    ios.Write(bVersitObject, bVersitObject.GetLowerBound(0), dataVersit.iDataLength); 
                    ios.Flush();
                    ios.Close();
                }
                else
                {
                    PCCAPIUtils.ShowErrorMessage("CAReadItem", iRet);
                }
                Marshal.FreeHGlobal(bufId);
                Marshal.FreeHGlobal(bufData);
                iRet = DAContentAccess.CAEndOperation(hOperHandle);
                if (iRet != PCCSErrors.CONA_OK)
                {
                    PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
                }
                FreeUIDMappingMemory(UID);
            }
        }

        private void BTN_NewFolder_Click(object sender, System.EventArgs e)
        {
            // Open "New Folder" dialog
            NewFolderDlg dlg = new NewFolderDlg();
            if (dlg.ShowDialog(this) != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }
            // Creates folder to currently connected device
            int hOperHandle = 0;
            int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0, ref hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
            }
            System.Windows.Forms.TreeNode treeNode = TVW_Navigator.SelectedNode;
            string strFolder;
            IntPtr buffer;
            if (treeNode.ImageIndex == m_iIconSMSMessagesIndex)
            {   // Fill item id struct
                CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID itemId = new CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID();
                itemId.iSize = Marshal.SizeOf(itemId);
                itemId.iFolderId = CADataDefinitions.CA_MESSAGE_FOLDER_USER_FOLDERS;
                buffer = Marshal.AllocHGlobal(Marshal.SizeOf(itemId));
                Marshal.StructureToPtr(itemId, buffer, true);
                // Create path for user defined message folder
                strFolder = "predefuserfolders\\" + dlg.TextFolder.Text;
                // Find SMS messages root folder
                while (treeNode.Parent.ImageIndex == m_iIconSMSMessagesIndex)
                {
                    treeNode = treeNode.Parent;
                }
            }
            else
            {
                CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO UID = MapCAFolderInfoToCFI((CAFolderInfo)TVW_Navigator.SelectedNode.Tag);
                // Browse folder up to current item root and
                // build path for new subfolder (root UID used for operation) 
                strFolder = dlg.TextFolder.Text;
                while ((treeNode.Parent != null))
                {
                    if ((treeNode.Parent.Tag != null))
                    {
                        UID = MapCAFolderInfoToCFI((CAFolderInfo)treeNode.Tag);
                        if (UID.pstrName != "\\")
                        {
                            strFolder = UID.pstrName + "\\" + strFolder;
                        }
                        treeNode = treeNode.Parent;
                    }
                }
                buffer = Marshal.AllocHGlobal(Marshal.SizeOf(UID));
                Marshal.StructureToPtr(UID, buffer, true);
            }
            iRet = DAContentAccess.CACreateFolder(hOperHandle, buffer, strFolder);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CACreateFolder", iRet);
            }
            iRet = DAContentAccess.CACommitOperations(hOperHandle, IntPtr.Zero);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CACommitOperations", iRet);
            }
            iRet = DAContentAccess.CAEndOperation(hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
            }
            Marshal.FreeHGlobal(buffer);

            // Fill connected devices, target folders and PIM items in tree view
            //RefreshTreeView()
            bRefresh = true;
        }

        //===================================================================
        // ShowNotification
        //
        // Asynchronously inserts notification text to Notifications dialog 
        //
        //===================================================================
        public void ShowNotification(string strNotification)
        {
            if (NotificationsDialog == null)
            {
                return;
            }
            if (NotificationsDialog.IsDisposed)
            {
                return;
            }
            // Insert text to Notifications dialog asynchronously, so that UI is not blocked
            BeginInvoke(new InsertNotificationDelegate(NotificationsDialog.InsertNotification), new Object[] {strNotification});
        }

        //===================================================================
        // CANotifyCallBack
        //
        // Callback function for CA notifications
        //
        //===================================================================
        public int CANotifyCallBack(int hCAHandle, int iReason, int iParam, IntPtr pItemID)
        {
            if (iReason == CAContentAccess.DAContentAccessDefinitions.CA_REASON_ENUMERATING)
                ShowNotification("CANotifyCallBack: CA_REASON_ENUMERATING");
            else if (iReason == CAContentAccess.DAContentAccessDefinitions.CA_REASON_ITEM_ADDED)
                ShowNotification("CANotifyCallBack: CA_REASON_ITEM_ADDED");
            else if (iReason == CAContentAccess.DAContentAccessDefinitions.CA_REASON_ITEM_DELETED)
                ShowNotification("CANotifyCallBack: CA_REASON_ITEM_DELETED");
            else if (iReason == CAContentAccess.DAContentAccessDefinitions.CA_REASON_ITEM_UPDATED)
                ShowNotification("CANotifyCallBack: CA_REASON_ITEM_UPDATED");
            else if (iReason == CAContentAccess.DAContentAccessDefinitions.CA_REASON_ITEM_MOVED)
                ShowNotification("CANotifyCallBack: CA_REASON_ITEM_MOVED");
            else if (iReason == CAContentAccess.DAContentAccessDefinitions.CA_REASON_ITEM_REPLACED)
                ShowNotification("CANotifyCallBack: CA_REASON_ITEM_REPLACED");
            else if (iReason == CAContentAccess.DAContentAccessDefinitions.CA_REASON_CONNECTION_LOST)
                ShowNotification("CANotifyCallBack: CA_REASON_CONNECTION_LOST");
            else if (iReason == CAContentAccess.DAContentAccessDefinitions.CA_REASON_MSG_DELIVERY)
                ShowNotification("CANotifyCallBack: CA_REASON_MSG_DELIVERY");
            return PCCSErrors.CONA_OK;
        }

        //===================================================================
        // CAOperationCallback
        //
        // Callback function for CA operation notifications
        //
        //===================================================================
        public int CAOperationCallback(int hOperHandle, int iOperation, int iCurrent, int iTotalAmount, int iStatus, IntPtr pItemID)
        {
            string strStatus = String.Format("CAOperationCallback: Operation({0}), progress({0}), total({0}), status({0})", iOperation, iCurrent, iTotalAmount, iStatus);
            ShowNotification(strStatus);
            return PCCSErrors.CONA_OK;
        }

        //===================================================================
        // TVW_Navigator_BeforeExpand
        //
        // User has clicked '+' in tree view
        //
        //===================================================================
        private void TVW_Navigator_BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
        {
            System.Windows.Forms.TreeNode item = e.Node;
            if (item.Parent == null)
            {
                // Phone item
                return;
            }
            if (item.FirstNode == null)
            {
                return;
            }
            System.Windows.Forms.TreeNode childItem = item.FirstNode;
            if ((childItem.Tag != null))
            {
                // Already expanded
                return;
            }
            Cursor = System.Windows.Forms.Cursors.WaitCursor;
            // Remove dummy item.
            childItem.Remove();
            string strSerialNumber = GetCurrentDevice(item);
            if (strSerialNumber == "0" || strSerialNumber.Length == 0)
            {
                return;
            }
            int iImage = item.ImageIndex;
            if (iImage == m_iIconContactsIndex)
            {
                // Check PIM connection to contacts folder and open it if needed
                CheckContactsConnection(strSerialNumber);
                GetContacts(strSerialNumber, item);
            }
            else if (iImage == m_iIconCalendarIndex)
            {
                // Check PIM connection to Calendar folders and open it if needed
                CheckCalendarConnection(strSerialNumber);
                GetCalendar(strSerialNumber, item);
            }
            else if (iImage == m_iIconBookmarkIndex)
            {
                // Check PIM connection to Bookmark folders and open it if needed
                CheckBookmarkConnection(strSerialNumber);
                GetBookmarks(strSerialNumber, item);
            }
            else if (iImage == m_iIconSMSMessagesIndex)
            {
                // Check PIM connection to SMS folders and open it if needed
                CheckSMSConnection(strSerialNumber);
                GetSMSMessages(strSerialNumber, item);
            }
            else if (iImage == m_iIconMMSMessagesIndex)
            {
                // Check PIM connection to MMS folders and open it if needed
                CheckMMSConnection(strSerialNumber);
                GetMMSMessages(strSerialNumber, item);
            }
            Cursor = System.Windows.Forms.Cursors.Default;
        }

        //===================================================================
        // ButtonNotifications_Click
        //
        // User has clicked "Notifications" button
        //
        //===================================================================
        private void buttonNotifications_Click(object sender, EventArgs e)
        {
            if (NotificationsDialog == null)
                NotificationsDialog = new NotificationsDlg();
            if (NotificationsDialog.IsDisposed)
                NotificationsDialog = new NotificationsDlg();
            NotificationsDialog.Show();
        }

        public bool InitSmsProcess()
        {
            try
            {
                //initialize API
                InitializePhoneAPI();

                //build the tree View
                RefreshTreeView();

                //get sms node
                _smsNode = SelectSmsOutBoxFolder(TVW_Navigator.Nodes[0]);

               TVW_Navigator.SelectedNode =  _smsNode;

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool SendSms(string number,string message)
        {
            try
            {
                // SMS folder selected
                m_hCurrentConnection = m_hSMS;
                MySendSms(number, message, _smsNode);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        private void MySendSms(string number,string message,TreeNode smsNode)
        {
            // Open "New Text Message" dialog
            CheckSMSConnection(GetCurrentDevice());
            CAContentAccess.CADataDefinitions.CA_DATA_MSG dataMsg = new CADataDefinitions.CA_DATA_MSG();
            dataMsg.iSize = Marshal.SizeOf(dataMsg);
            CADataDefinitions.CA_SET_DATA_FORMAT(ref dataMsg.iInfoField, CADataDefinitions.CA_DATA_FORMAT_UNICODE);
            CADataDefinitions.CA_SET_DATA_CODING(ref dataMsg.iInfoField, CADataDefinitions.CA_DATA_CODING_UNICODE);
            CADataDefinitions.CA_SET_MESSAGE_STATUS(ref dataMsg.iInfoField, CADataDefinitions.CA_MESSAGE_STATUS_DRAFT);
            CADataDefinitions.CA_SET_MESSAGE_TYPE(ref dataMsg.iInfoField, CADataDefinitions.CA_SMS_SUBMIT);
            // Phone number
            if ((number.Length > 0))
            {
                dataMsg.bAddressCount = 1;
                dataMsg.pAddress = GetSMSAddressBuffer(number);
            }
            // Message body text
            int iLength = message.Length;
            if ((iLength > 0))
            {
                dataMsg.iDataLength = iLength*2;
                dataMsg.pbData = Marshal.StringToCoTaskMemUni(message);
            }
            // Set message date
            GetCurrentPIMDate(ref dataMsg.messageDate);
            
            CAContentAccess.DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;
            folderInfo = MapCAFolderInfoToCFI((CAFolderInfo) smsNode.Tag);
            
            // Write new SMS item to currently connected device
            int hOperHandle = 0;
            int iRet = DAContentAccess.CABeginOperation(m_hCurrentConnection, 0, ref hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CABeginOperation", iRet);
            }
            CAContentAccess.DAContentAccess.CARegisterOperationCallback(hOperHandle, CONADefinitions.API_REGISTER,
                                                                        pCAOperationCallback);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterOperationCallback", iRet);
            CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID itemUid = new DAContentAccessDefinitions.CA_ITEM_ID();
            itemUid.iSize = Marshal.SizeOf(itemUid);
            itemUid.iFolderId = folderInfo.iFolderId;
            itemUid.iFolderId = folderInfo.iFolderId;
            itemUid.iStatus = 0;
            itemUid.iTemporaryID = 0;
            itemUid.iUidLen = 0;
            itemUid.pbUid = IntPtr.Zero;
            IntPtr buf =
                Marshal.AllocHGlobal(Marshal.SizeOf(typeof (CAContentAccess.DAContentAccessDefinitions.CA_ITEM_ID)));
            Marshal.StructureToPtr(itemUid, buf, true);
            // Allocate memory for buffer
            IntPtr buf2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof (CAContentAccess.CADataDefinitions.CA_DATA_MSG)));
            Marshal.StructureToPtr(dataMsg, buf2, true);
            iRet = DAContentAccess.CAWriteItem(hOperHandle, buf, 0, CADataDefinitions.CA_DATA_FORMAT_STRUCT, buf2);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("DAWriteItem", iRet);
            Marshal.FreeHGlobal(buf2);
            Marshal.FreeHGlobal(buf);

            //If iRet <> PCCSErrors.CONA_OK Then PCCAPIUtils.ShowErrorMessage("DAFreeItemData", iRet)
            Marshal.FreeCoTaskMem(dataMsg.pbData);
            Marshal.FreeCoTaskMem(dataMsg.pAddress);

            iRet = DAContentAccess.CACommitOperations(hOperHandle, IntPtr.Zero);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CACommitOperations", iRet);
            }
            CAContentAccess.DAContentAccess.CARegisterOperationCallback(hOperHandle, CONADefinitions.API_UNREGISTER,
                                                                        pCAOperationCallback);
            if (iRet != PCCSErrors.CONA_OK) PCCAPIUtils.ShowErrorMessage("CARegisterOperationCallback", iRet);
            iRet = DAContentAccess.CAEndOperation(hOperHandle);
            if (iRet != PCCSErrors.CONA_OK)
            {
                PCCAPIUtils.ShowErrorMessage("CAEndOperation", iRet);
            }
            smsNode.Nodes.Clear();
            GetSMSMessages(GetCurrentDevice(), smsNode);
        }

        private static TreeNode SelectSmsOutBoxFolder(TreeNode pnode)
        {
            TreeNode node = null;
            foreach (TreeNode childNode in pnode.Nodes)
            {
                if (childNode.Text == "predefoutbox")
                    node = childNode;
                else if (childNode.Nodes.Count>0)
                    node = SelectSmsOutBoxFolder(childNode);
                if(node!=null)
                    break;
            }
            return node;
        }
    }
}
